mirror of https://github.com/l4ka/hazelnut.git
Initial revision
This commit is contained in:
commit
cc4849186b
|
@ -0,0 +1 @@
|
|||
.dump
|
|
@ -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
|
|
@ -0,0 +1 @@
|
|||
Makeconf.local
|
|
@ -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 <somepath>/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)
|
|
@ -0,0 +1,3 @@
|
|||
PLATFORM=i586
|
||||
SIGMA0_LINKBASE=00020000
|
||||
ROOTTASK_LINKBASE=
|
|
@ -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`
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
*.ii *.s
|
||||
*.bin *.stripped
|
||||
modules.*
|
||||
arm-booter
|
|
@ -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 <l4/l4.h>" >> 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 <l4io.h>" >> 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 { .$(<F) : { *(.data); . = ALIGN(4); } }" > $<.lnk
|
||||
@(cd tmp;$(LD) -T $(<F).lnk -r --oformat default -o $(@F) -bbinary $(<F))
|
||||
@rm $<.lnk
|
||||
|
||||
clean::
|
||||
rm -v -f $(TARGET)* modules.* tmp/[^C]*
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/crt0-arm-brutus.S
|
||||
* Description: startup assembly code for Brutus (AngelBoot)
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: crt0-arm-brutus.S,v 1.3 2001/12/09 04:06:30 ud3 Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
/* Request SVC mode from Angel */
|
||||
mov r0, #0x17
|
||||
swi #0x123456
|
||||
|
||||
/* Turn off interrupts to keep control */
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0xC0
|
||||
msr cpsr, r0
|
||||
|
||||
/* Clean out the DCache */
|
||||
mov r2, pc
|
||||
bic r2, r2, #0x1f
|
||||
add r3, r2, #0x10000 @ 64 kb is quite enough...
|
||||
1: ldr r0, [r2], #32
|
||||
teq r2, r3
|
||||
bne 1b
|
||||
|
||||
mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf
|
||||
|
||||
/* Disable MMU and Caches */
|
||||
mrc p15, 0, r0, c1, c0
|
||||
ldr r1, =0x100d
|
||||
bic r0, r0, r1
|
||||
mcr p15, 0, r0, c1, c0
|
||||
|
||||
/* Clean out caches and TLBs */
|
||||
mcr p15, 0, r0, c7, c7, 0 @ Flush I+D cache
|
||||
mcr p15, 0, r0, c8, c7, 0 @ Flush I+D TLBs on v4
|
||||
|
||||
ldr r1, =0x90040000 @ Load GPIO PBase
|
||||
ldr r0, =0x00100000 @ Set relevant output GPIOs
|
||||
str r0, [r1, #0xc]
|
||||
|
||||
#define SLEEP ; \
|
||||
mov r1, #0x800000 ; \
|
||||
0: subs r1, r1, #1 ; \
|
||||
bne 0b
|
||||
|
||||
ldr r1, =0x80050000
|
||||
|
||||
/* Disable UART */
|
||||
mov r0, #0x00 @ disable ints/RX/TX
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
/* Clear Serial Interrupts */
|
||||
ldr r0, =0xFF
|
||||
str r0, [r1, #0x1c] @ Clear Stat Reg 0
|
||||
|
||||
/* Set to (N81) No Parity, 8bit data, 1 stop bit, internal clock */
|
||||
ldr r0, =0x8
|
||||
str r0, [r1, #0x00] @ Set Cntr Reg 0
|
||||
|
||||
/* Set to Baud Rate of 115200 */
|
||||
mov r0, #0x00
|
||||
str r0, [r1, #0x04] @ Set Cntr Reg 1
|
||||
ldr r0, =0x001
|
||||
str r0, [r1, #0x08] @ Set Cntr Reg 2
|
||||
|
||||
/* Enable Transmit and Receive, Interrupts Masked */
|
||||
ldr r0, =0x3
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
SLEEP
|
||||
|
||||
/* here we actually start */
|
||||
2: ldr sp, =__stack_top
|
||||
bl main
|
||||
1: b 1b
|
||||
|
||||
.globl __gccmain
|
||||
__gccmain:
|
||||
mov pc,lr
|
||||
|
||||
.bss
|
||||
.align 2
|
||||
__stack_bottom:
|
||||
.space 1024
|
||||
__stack_top:
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/crt0-arm-dnard.S
|
||||
* Description: startup assembly code for DNARD board
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: crt0-arm-dnard.S,v 1.5 2001/12/11 19:54:22 ud3 Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
/*
|
||||
DNARD initial memory map
|
||||
|
||||
virt phys size
|
||||
F0000000 0e500000
|
||||
F7EFF000 40000000 4k
|
||||
|
||||
|
||||
We're loaded at f0000000, backed by 0e500000. This code is linked at
|
||||
0e500000. Thus the ldr r2,=1f will load 0e5000xy, not f00000xy. By
|
||||
jumping to r2 directly after turning off the MMU, we then run 1:1
|
||||
|
||||
*/
|
||||
.globl _start
|
||||
_start:
|
||||
/* Turn off interrupts to keep control */
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0xC0 /* IRQs and FIQs disabled */
|
||||
msr cpsr, r0
|
||||
|
||||
/* Clean out the DCache */
|
||||
mrc p15, 0, r3, c1, c0
|
||||
bic r3, r3, #0xC /* Write Buffer and DCache */
|
||||
bic r3, r3, #0x1000 /* ICache */
|
||||
mcr p15, 0, r3, c1, c0 /* disabled */
|
||||
bic r3, r3, #0x1 /* prepare disabling of MMU */
|
||||
|
||||
ldr r2, =1f /* load target address to jump
|
||||
to when MMU is off */
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7 /* flush I,D caches on v4 */
|
||||
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer on v4 */
|
||||
mcr p15, 0, r0, c8, c7 /* flush I,D TLBs on v4
|
||||
The next 4 instructions are
|
||||
fetched still using the just
|
||||
flushed TLB entries */
|
||||
|
||||
mcr p15, 0, r3, c1, c0 /* disable MMU */
|
||||
mov pc, r2 /* jump to the next instruction */
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
1:
|
||||
|
||||
#define SLEEP \
|
||||
mov r1, #0x10000 ; 0: subs r1, r1, #1; bne 0b
|
||||
|
||||
ldr r0, =0x400003f8
|
||||
mov r1, #0
|
||||
strb r1, [r0, #0x01] /* disable serial interrupt */
|
||||
SLEEP
|
||||
mov r1, #0x80
|
||||
strb r1, [r0, #0x03] /* switch to divisor mode */
|
||||
SLEEP
|
||||
mov r1, #1
|
||||
strb r1, [r0, #0x00] /* DLLO */
|
||||
SLEEP
|
||||
mov r1, #0
|
||||
strb r1, [r0, #0x01] /* DLHI */
|
||||
SLEEP
|
||||
mov r1, #0x03
|
||||
strb r1, [r0, #0x03] /* switch back */
|
||||
SLEEP
|
||||
mov r1, #0x06
|
||||
strb r1, [r0, #0x02] /* FCR */
|
||||
SLEEP
|
||||
mov r1, #0x00
|
||||
strb r1, [r0, #0x01] /* FCR */
|
||||
|
||||
SLEEP
|
||||
|
||||
ldr r1, [r0, #1]
|
||||
ldr r1, [r0, #2]
|
||||
ldr r1, [r0, #3]
|
||||
ldr r1, [r0, #4]
|
||||
ldr r1, [r0, #5]
|
||||
ldr r1, [r0, #6]
|
||||
|
||||
SLEEP
|
||||
|
||||
#if 0
|
||||
mov r2, #0x39
|
||||
1: ldr r0, =0x400003f8
|
||||
strb r2, [r0]
|
||||
SLEEP
|
||||
sub r2, r2, #1
|
||||
cmp r2, #0x2F
|
||||
bne 1b
|
||||
#endif
|
||||
|
||||
/* here we actually start */
|
||||
2: ldr sp, =__stack_top
|
||||
bl main
|
||||
1: b 1b
|
||||
|
||||
.globl __gccmain
|
||||
__gccmain:
|
||||
mov pc,lr
|
||||
|
||||
|
||||
.bss
|
||||
.align 4
|
||||
__stack_bottom:
|
||||
.space 1024
|
||||
__stack_top:
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,87 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/crt0-arm-ep7211.S
|
||||
* Description: startup assembly code for EP7211
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: crt0-arm-ep7211.S,v 1.3 2001/12/09 04:06:30 ud3 Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
/* Turn off interrupts to keep control */
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0xC0 /* IRQs and FIQs disabled */
|
||||
msr cpsr, r0
|
||||
|
||||
/* Clean out the DCache */
|
||||
mrc p15, 0, r3, c1, c0
|
||||
bic r3, r3, #0xC /* Write Buffer and DCache */
|
||||
bic r3, r3, #0x1000 /* ICache */
|
||||
mcr p15, 0, r3, c1, c0 /* disabled */
|
||||
|
||||
mov r0, #0
|
||||
mcr p15, 0, r0, c7, c7 /* flush I,D caches on v4 */
|
||||
mcr p15, 0, r0, c7, c10, 4 /* drain write buffer on v4 */
|
||||
mcr p15, 0, r0, c8, c7 /* flush I,D TLBs on v4 */
|
||||
|
||||
ldr r2, =1f
|
||||
|
||||
2: bic r3, r3, #0x1 /* MMU */
|
||||
mcr p15, 0, r3, c1, c0 /* disabled */
|
||||
|
||||
mov pc, r2 /* jump to the next instruction */
|
||||
1:
|
||||
|
||||
#define SLEEP \
|
||||
mov r1, #0x10000 ; 0: subs r1, r1, #1; bne 0b
|
||||
|
||||
|
||||
#define HwBaseAddress2 0x80001000
|
||||
#define HwControl 0x00000100
|
||||
#define HwControlUartEnable 0x00000100
|
||||
#define HwStatus 0x00000140
|
||||
#define CLKMOD 0x00000040
|
||||
#define UartValue (0x00000001 | 0x00070000)
|
||||
#define UartValue_13 (0x00000000 | 0x00070000)
|
||||
#define HwUartControl 0x000004C0
|
||||
#define HwUartData 0x00000480
|
||||
|
||||
/* LED Flasher */
|
||||
ldr r0, =0x800022c0
|
||||
mov r1, #((1 << 6) | (0x7 << 2) | 0)
|
||||
// str r1, [r0]
|
||||
|
||||
ldr r12, =HwBaseAddress2
|
||||
mov r0, #HwControlUartEnable /* UART enable */
|
||||
str r0, [r12, #HwControl] /* write HwControl */
|
||||
|
||||
ldr r1, =HwStatus
|
||||
add r1, r1, r12
|
||||
ldr r2, [r1]
|
||||
tst r2, #CLKMOD /* figure out which */
|
||||
ldreq r0, =UartValue /* rate setting to use */
|
||||
ldrne r0, =UartValue_13
|
||||
str r0, [r12, #HwUartControl]
|
||||
|
||||
/* here we actually start */
|
||||
2: ldr sp, =__stack_top
|
||||
bl main
|
||||
1: b 1b
|
||||
|
||||
.globl __gccmain
|
||||
__gccmain:
|
||||
mov pc,lr
|
||||
|
||||
|
||||
.bss
|
||||
.align 4
|
||||
__stack_bottom:
|
||||
.space 1024
|
||||
__stack_top:
|
||||
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/crt0-arm-ipaq.S
|
||||
* Description: startup assembly code for IPaq (bootldr)
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: crt0-arm-ipaq.S,v 1.1 2002/01/24 07:19:31 uhlig Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
.globl _start
|
||||
_start:
|
||||
b hmm
|
||||
/* Turn off interrupts to keep control */
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0xC0
|
||||
msr cpsr, r0
|
||||
#if 0
|
||||
/* Clean out the DCache */
|
||||
mov r2, pc
|
||||
bic r2, r2, #0x1f
|
||||
add r3, r2, #0x10000 @ 64 kb is quite enough...
|
||||
1: ldr r0, [r2], #32
|
||||
teq r2, r3
|
||||
bne 1b
|
||||
|
||||
mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf
|
||||
#endif
|
||||
/* Disable MMU and Caches */
|
||||
mrc p15, 0, r0, c1, c0
|
||||
ldr r1, =0x100d
|
||||
bic r0, r0, r1
|
||||
mcr p15, 0, r0, c1, c0
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
/* Clean out caches and TLBs */
|
||||
mcr p15, 0, r0, c7, c7, 0 @ Flush I+D cache
|
||||
mcr p15, 0, r0, c8, c7, 0 @ Flush I+D TLBs on v4
|
||||
|
||||
ldr r1, =0x90040000 @ Load GPIO PBase
|
||||
ldr r0, =0x00100000 @ Set relevant output GPIOs
|
||||
str r0, [r1, #0xc]
|
||||
|
||||
#define SLEEP ; \
|
||||
mov r1, #0x800000 ; \
|
||||
0: subs r1, r1, #1 ; \
|
||||
bne 0b
|
||||
|
||||
ldr r1, =0x80050000
|
||||
|
||||
/* Disable UART */
|
||||
mov r0, #0x00 @ disable ints/RX/TX
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
/* Clear Serial Interrupts */
|
||||
ldr r0, =0xFF
|
||||
str r0, [r1, #0x1c] @ Clear Stat Reg 0
|
||||
|
||||
/* Set to (N81) No Parity, 8bit data, 1 stop bit, internal clock */
|
||||
ldr r0, =0x8
|
||||
str r0, [r1, #0x00] @ Set Cntr Reg 0
|
||||
|
||||
/* Set to Baud Rate of 115200 */
|
||||
mov r0, #0x00
|
||||
str r0, [r1, #0x04] @ Set Cntr Reg 1
|
||||
ldr r0, =0x001
|
||||
str r0, [r1, #0x08] @ Set Cntr Reg 2
|
||||
|
||||
/* Enable Transmit and Receive, Interrupts Masked */
|
||||
ldr r0, =0x3
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
SLEEP
|
||||
hmm:
|
||||
/* here we actually start */
|
||||
2: ldr sp, =__stack_top
|
||||
bl main
|
||||
1: b 1b
|
||||
|
||||
.globl __gccmain
|
||||
__gccmain:
|
||||
mov pc,lr
|
||||
|
||||
.bss
|
||||
.align 2
|
||||
__stack_bottom:
|
||||
.space 1024
|
||||
__stack_top:
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2002, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/crt0-arm-pleb.S
|
||||
* Description: PLEB-specific startup code
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: crt0-arm-pleb.S,v 1.1 2002/02/03 22:26:53 ud3 Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
.globl _start
|
||||
_start:
|
||||
/* Request SVC mode from Angel */
|
||||
/*
|
||||
mov r0, #0x17
|
||||
swi #0x123456
|
||||
*/
|
||||
|
||||
/* Turn off interrupts to keep control */
|
||||
mrs r0, cpsr
|
||||
orr r0, r0, #0xC0
|
||||
msr cpsr, r0
|
||||
|
||||
|
||||
/* Clean out the DCache */
|
||||
mov r2, pc
|
||||
bic r2, r2, #0x1f
|
||||
add r3, r2, #0x10000 @ 64 kb is quite enough...
|
||||
1: ldr r0, [r2], #32
|
||||
teq r2, r3
|
||||
bne 1b
|
||||
|
||||
mcr p15, 0, r0, c7, c10, 4 @ Drain writebuf
|
||||
|
||||
/* Disable MMU and Caches */
|
||||
mrc p15, 0, r0, c1, c0
|
||||
ldr r1, =0x100d
|
||||
bic r0, r0, r1
|
||||
mcr p15, 0, r0, c1, c0
|
||||
|
||||
/* Clean out caches and TLBs */
|
||||
mcr p15, 0, r0, c7, c7, 0 @ Flush I+D cache
|
||||
mcr p15, 0, r0, c8, c7, 0 @ Flush I+D TLBs on v4
|
||||
|
||||
ldr r1, =0x90040000 @ Load GPIO PBase
|
||||
ldr r0, =0x00100000 @ Set relevant output GPIOs
|
||||
str r0, [r1, #0xc]
|
||||
|
||||
#define SLEEP ; \
|
||||
mov r1, #0x800000 ; \
|
||||
0: subs r1, r1, #1 ; \
|
||||
bne 0b
|
||||
|
||||
#ifdef CONFIG_UART
|
||||
ldr r1, =0x80050000
|
||||
|
||||
/* Disable UART */
|
||||
mov r0, #0x00 @ disable ints/RX/TX
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
/* Clear Serial Interrupts */
|
||||
ldr r0, =0xFF
|
||||
str r0, [r1, #0x1c] @ Clear Stat Reg 0
|
||||
|
||||
/* Set to (N81) No Parity, 8bit data, 1 stop bit, internal clock */
|
||||
ldr r0, =0x8
|
||||
str r0, [r1, #0x00] @ Set Cntr Reg 0
|
||||
|
||||
/* Set to Baud Rate of 115200 */
|
||||
/* Set BRD to 1, for a baudrate of 115k2 ([1] 11.11.4.1) */
|
||||
/* Set BRD to 5, for a baudrate of 38k4 ([1] 11.11.4.1) */
|
||||
/* Set BRD to 23, for a baudrate of 9k6 ([1] 11.11.4.1) */
|
||||
mov r0, #0x00
|
||||
str r0, [r1, #0x04] @ Set Cntr Reg 1
|
||||
ldr r0, =0x23
|
||||
str r0, [r1, #0x08] @ Set Cntr Reg 2
|
||||
|
||||
/* Enable Transmit and Receive, Interrupts Masked */
|
||||
ldr r0, =0x3
|
||||
str r0, [r1, #0x0c] @ Set Cntr Reg 3
|
||||
|
||||
/* SLEEP */
|
||||
#endif
|
||||
/* Send out a welcome message */
|
||||
adr r0, welcome
|
||||
bl print_str
|
||||
|
||||
/* here we actually start */
|
||||
2: ldr sp, =__stack_top
|
||||
bl main
|
||||
1: b 1b
|
||||
|
||||
.globl __gccmain
|
||||
__gccmain:
|
||||
mov pc,lr
|
||||
|
||||
.align 4
|
||||
welcome:
|
||||
.string "Armbooter started...\n\r"
|
||||
|
||||
.align 4
|
||||
/* Utility functions */
|
||||
|
||||
/* Subroutine that sends a string over the serial port */
|
||||
/* The address of the string should be in r0 */
|
||||
print_str:
|
||||
/* Save the return address */
|
||||
mov r13, r14
|
||||
mov r2, r0
|
||||
prs1:
|
||||
ldrsb r0, [r2]
|
||||
add r2, r2, #0x01
|
||||
ands r0, r0, #0xFF
|
||||
beq prs2
|
||||
bl print_byte
|
||||
b prs1
|
||||
|
||||
prs2:
|
||||
/* Return */
|
||||
mov pc, r13
|
||||
|
||||
|
||||
/* Subroutine that sends a byte over the serial port. */
|
||||
/* The byte is in r0 */
|
||||
print_byte:
|
||||
/* Wait for room in the tx fifo */
|
||||
mov r1, #0x80000000
|
||||
add r1, r1, #0x50000
|
||||
|
||||
ldr r1, [r1, #0x1C]
|
||||
ands r1, r1, #0x01
|
||||
beq print_byte
|
||||
|
||||
mov r1, #0x80000000
|
||||
add r1, r1, #0x50000
|
||||
|
||||
str r0, [r1, #0x14]
|
||||
mov pc, r14
|
||||
|
||||
|
||||
/* stack */
|
||||
|
||||
.bss
|
||||
.align 2
|
||||
__stack_bottom:
|
||||
.space 4096
|
||||
__stack_top:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*********************************************************************
|
||||
*
|
||||
* Copyright (C) 2001, Karlsruhe University
|
||||
*
|
||||
* File path: arm-booter/elf.c
|
||||
* Description: tiny ELF file loader
|
||||
*
|
||||
* @LICENSE@
|
||||
*
|
||||
* $Id: elf.c,v 1.4 2001/12/09 04:06:30 ud3 Exp $
|
||||
*
|
||||
********************************************************************/
|
||||
|
||||
#include "elf.h"
|
||||
#include <l4io.h>
|
||||
|
||||
#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");
|
||||
};
|
File diff suppressed because it is too large
Load Diff
|
@ -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 = .;
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
#include <l4/arm/kernel.h>
|
||||
#include <l4io.h>
|
||||
|
||||
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);
|
||||
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
*
|
|
@ -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
|
||||
|
|
@ -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 <l4/l4.h>
|
||||
#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));
|
||||
}
|
|
@ -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__ */
|
|
@ -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:
|
|
@ -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 <l4/l4.h>
|
||||
#include <l4/helpers.h>
|
||||
#include <l4/sigma0.h>
|
||||
#include <l4io.h>
|
||||
#include <multiboot.h>
|
||||
|
||||
#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");
|
||||
}
|
|
@ -0,0 +1,226 @@
|
|||
#include <l4/l4.h>
|
||||
#include <l4io.h>
|
||||
|
||||
|
||||
#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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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 <config.h>
|
||||
|
||||
.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:
|
|
@ -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:
|
|
@ -0,0 +1,352 @@
|
|||
#include <l4/l4.h>
|
||||
|
||||
#include <l4/helpers.h>
|
||||
#include <l4io.h>
|
||||
|
||||
|
||||
//#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");
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
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
|
|
@ -0,0 +1 @@
|
|||
config.h
|
|
@ -0,0 +1 @@
|
|||
x86
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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 <l4/arch/types.h>
|
||||
*/
|
||||
|
||||
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 <l4/arch/types.h>
|
||||
*/
|
||||
#include <config.h>
|
||||
#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 <l4/arch/l4.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !__L4__L4_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__ */
|
|
@ -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__ */
|
|
@ -0,0 +1,40 @@
|
|||
#ifndef __L4_I386_RMGR_H
|
||||
#define __L4_I386_RMGR_H
|
||||
|
||||
#include <l4/arch/types.h>
|
||||
|
||||
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
|
|
@ -0,0 +1,56 @@
|
|||
#ifndef __L4_SERVER_RMGR_H__
|
||||
#define __L4_SERVER_RMGR_H__
|
||||
|
||||
#include <l4/rmgr/server_proto.h>
|
||||
|
||||
#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
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __L4_SERVER_PROTO_H__
|
||||
#define __L4_SERVER_PROTO_H__
|
||||
|
||||
#include <l4/l4.h>
|
||||
|
||||
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
|
|
@ -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__ */
|
|
@ -0,0 +1 @@
|
|||
arch/sys
|
|
@ -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 <linux/linkage.h>
|
||||
|
||||
#endif
|
|
@ -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__ */
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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__ */
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -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__ */
|
|
@ -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 <l4/arch/types.h>
|
||||
*/
|
||||
|
||||
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 <l4/x86/l4.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !__L4__L4_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 <linux/linkage.h>
|
||||
|
||||
#endif
|
|
@ -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__ */
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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__
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -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__ */
|
|
@ -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 */
|
|
@ -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 <l4/arch/types.h>
|
||||
*/
|
||||
|
||||
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 <l4/x86/l4.h>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif /* !__L4__L4_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 <linux/linkage.h>
|
||||
|
||||
#endif
|
|
@ -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);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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__ */
|
||||
|
|
@ -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__ */
|
|
@ -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
|
|
@ -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__
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -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__ */
|
||||
|
||||
|
|
@ -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
|
|
@ -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 $@ $^
|
||||
|
|
@ -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 <l4/l4.h>
|
||||
#include <l4/libide.h>
|
||||
|
||||
#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;
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
.depend
|
|
@ -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)
|
|
@ -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 <l4/l4.h>
|
||||
#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 );
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
#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');
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
|
||||
#include "arm-dnard-uart.h"
|
||||
|
||||
int getc(void)
|
||||
{
|
||||
while (!(STATUS(COM1) & 0x01));
|
||||
return DATA(COM1);
|
||||
};
|
||||
|
||||
|
|
@ -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 <l4/l4.h>
|
||||
|
||||
#include "arm-dnard-uart.h"
|
||||
|
||||
void putc(int c)
|
||||
{
|
||||
while (!(STATUS(COM1) & 0x60));
|
||||
DATA(COM1) = c;
|
||||
|
||||
if (c == '\n')
|
||||
putc('\r');
|
||||
};
|
||||
|
|
@ -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))
|
|
@ -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 $
|
||||
*
|
||||
********************************************************************/
|
|
@ -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 <l4/l4.h>
|
||||
#include "arm-ep7211-uart.h"
|
||||
|
||||
void putc(int c)
|
||||
{
|
||||
while (STATUS(HWBASE2) & UTXFF);
|
||||
DATA(HWBASE2) = c;
|
||||
|
||||
if (c == '\n')
|
||||
putc('\r');
|
||||
}
|
|
@ -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)
|
|
@ -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 <l4/l4.h>
|
||||
#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 );
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
#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');
|
||||
}
|
|
@ -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 */
|
|
@ -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 <l4/l4.h>
|
||||
#include <l4io.h>
|
||||
|
||||
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;
|
||||
}
|
|
@ -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 <l4io.h>
|
||||
#include <l4/l4.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
|
@ -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 */
|
|
@ -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 <l4/l4.h>
|
||||
#include <stdarg.h>
|
||||
#include <l4io.h>
|
||||
|
||||
/*
|
||||
* 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;
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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 <l4/l4.h>
|
||||
|
||||
#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
|
|
@ -0,0 +1,2 @@
|
|||
.depend
|
||||
|
|
@ -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
|
|
@ -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 <L4/arch/syscalls.h>
|
|
@ -0,0 +1 @@
|
|||
.depend
|
|
@ -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 $@ $^
|
||||
|
|
@ -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 <l4/l4.h>
|
||||
#include <l4io.h>
|
||||
|
||||
|
||||
#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;
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue