commit 11c151b60e5605b5ba5c193fbf8e312a8cfa6eac Author: Ali Mashtizadeh Date: Wed Feb 12 13:47:13 2014 -0800 Initial commit diff --git a/SConstruct b/SConstruct new file mode 100644 index 0000000..ed7b765 --- /dev/null +++ b/SConstruct @@ -0,0 +1,135 @@ +import sys +import os +import multiprocessing +import SCons.Util + +## Configuration + +opts = Variables('Local.sc') + +opts.AddVariables( + ("CC", "C Compiler"), + ("CXX", "C++ Compiler"), + ("AS", "Assembler"), + ("LINK", "Linker"), + ("BUILDTYPE", "Build type (RELEASE, DEBUG, or PERF)", "RELEASE"), + ("VERBOSE", "Show full build information (0 or 1)", "0"), + ("NUMCPUS", "Number of CPUs to use for build (0 means auto).", "0"), + ("WITH_GPROF", "Include gprof profiling (0 or 1).", "0"), + ("PREFIX", "Installation target directory.", "#pxelinux"), + ("ARCH", "Target Architecture", "amd64") +) + +env = Environment(options = opts, + tools = ['default'], + ENV = os.environ) +Help(opts.GenerateHelpText(env)) + +# Copy environment variables +if os.environ.has_key('CC'): + env["CC"] = os.getenv('CC') +if os.environ.has_key('CXX'): + env["CXX"] = os.getenv('CXX') +if os.environ.has_key('AS'): + env["AS"] = os.getenv('AS') +if os.environ.has_key('LD'): + env["LINK"] = os.getenv('LD') +if os.environ.has_key('CFLAGS'): + env.Append(CCFLAGS = SCons.Util.CLVar(os.environ['CFLAGS'])) +if os.environ.has_key('CPPFLAGS'): + env.Append(CPPFLAGS = SCons.Util.CLVar(os.environ['CPPFLAGS'])) +if os.environ.has_key('CXXFLAGS'): + env.Append(CXXFLAGS = SCons.Util.CLVar(os.environ['CXXFLAGS'])) +if os.environ.has_key('LDFLAGS'): + env.Append(LINKFLAGS = SCons.Util.CLVar(os.environ['LDFLAGS'])) + +#env.Append(CPPFLAGS = [ "-Wall", "-Wformat=2", "-Wextra", "-Wwrite-strings", +# "-Wno-unused-parameter", "-Wmissing-format-attribute", +# "-Werror" ]) +#env.Append(CFLAGS = [ "-Wmissing-prototypes", "-Wmissing-declarations", +# "-Wshadow", "-Wbad-function-cast", "-Werror" ]) +#env.Append(CXXFLAGS = [ "-Wno-non-template-friend", "-Woverloaded-virtual", +# "-Wcast-qual", "-Wcast-align", "-Wconversion", +# "-Weffc++", "-std=c++0x", "-Werror" ]) + +if env["WITH_GPROF"] == "1": + env.Append(CPPFLAGS = [ "-pg" ]) + env.Append(LINKFLAGS = [ "-pg" ]) + +if env["BUILDTYPE"] == "DEBUG": + env.Append(CPPFLAGS = [ "-g", "-DDEBUG", "-Wall", + "-Wno-deprecated-declarations" ]) + env.Append(LINKFLAGS = [ "-g", "-rdynamic" ]) +elif env["BUILDTYPE"] == "PERF": + env.Append(CPPFLAGS = [ "-g", "-DNDEBUG", "-Wall", "-O2"]) + env.Append(LDFLAGS = [ "-g", "-rdynamic" ]) +elif env["BUILDTYPE"] == "RELEASE": + env.Append(CPPFLAGS = ["-DNDEBUG", "-Wall", "-O2"]) +else: + print "Error BUILDTYPE must be RELEASE or DEBUG" + sys.exit(-1) + +if env["ARCH"] != "amd64": + print "Unsupported architecture: " + env["ARCH"] + sys.exit(-1) + +try: + hf = open(".git/HEAD", 'r') + head = hf.read() + if head.startswith("ref: "): + if head.endswith("\n"): + head = head[0:-1] + with open(".git/" + head[5:]) as bf: + branch = bf.read() + if branch.endswith("\n"): + branch = branch[0:-1] + env.Append(CPPFLAGS = [ "-DGIT_VERSION=\\\"" + branch + "\\\""]) +except IOError: + pass + +if env["VERBOSE"] == "0": + env["CCCOMSTR"] = "Compiling $SOURCE" + env["CXXCOMSTR"] = "Compiling $SOURCE" + env["SHCCCOMSTR"] = "Compiling $SOURCE" + env["SHCXXCOMSTR"] = "Compiling $SOURCE" + env["ARCOMSTR"] = "Creating library $TARGET" + env["RANLIBCOMSTR"] = "Indexing library $TARGET" + env["LINKCOMSTR"] = "Linking $TARGET" + +def GetNumCPUs(env): + if env["NUMCPUS"] != "0": + return int(env["NUMCPUS"]) + return 2*multiprocessing.cpu_count() + +env.SetOption('num_jobs', GetNumCPUs(env)) + +# XXX: Hack to support clang static analyzer +def CheckFailed(): + if os.getenv('CCC_ANALYZER_OUTPUT_FORMAT') != None: + return + Exit(1) + +# Configuration +conf = env.Configure() + +if not conf.CheckCC(): + print 'Your C compiler and/or environment is incorrectly configured.' + CheckFailed() + +if not conf.CheckCXX(): + print 'Your C++ compiler and/or environment is incorrectly configured.' + CheckFailed() + +conf.Finish() + +Export('env') + +# Debugging Tools + +# Build Targets +SConscript('sys/SConscript', variant_dir='build/sys') + +# Install Targets +env.Install('$PREFIX/','build/sys/castor') +env.Alias('install','$PREFIX') + diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 0000000..af05822 --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,24 @@ +#ifndef __STDARG_H_ +#define __STDARG_H_ + +#ifndef _VA_LIST_DECLARED +#define _VA_LIST_DECLARED +typedef __builtin_va_list va_list; +#endif + +#define va_start(ap, last) \ + __builtin_va_start((ap), (last)) + +#define va_arg(ap, type) \ + __builtin_va_arg((ap), type) + +#define __va_copy(dest, src) \ + __builtin_va_copy((dest), (src)) + +#define va_copy(dest, src) \ + __va_copy(dest, src) + +#define va_end(ap) \ + __builtin_va_end(ap) + +#endif /* __STDARG_H_ */ diff --git a/include/stddef.h b/include/stddef.h new file mode 100644 index 0000000..43f38f5 --- /dev/null +++ b/include/stddef.h @@ -0,0 +1,10 @@ + +#ifndef __STDDEF_H__ +#define __STDDEF_H__ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#endif /* __STDDEF_H__ */ + diff --git a/include/stdint.h b/include/stdint.h new file mode 100644 index 0000000..824cf1b --- /dev/null +++ b/include/stdint.h @@ -0,0 +1,22 @@ + +#ifndef _STDINT_H_ +#define _STDINT_H_ + +typedef signed char int8_t; +typedef signed short int16_t; +typedef signed int int32_t; +typedef signed long long int64_t; + +typedef unsigned char uint8_t; +typedef unsigned short uint16_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +typedef int64_t intptr_t; +typedef uint64_t uintptr_t; + +typedef uint64_t size_t; +typedef int64_t ssize_t; + +#endif /* _STDINT_H_ */ + diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..5423ca0 --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,10 @@ + +#ifndef __STDLIB_H__ +#define __STDLIB_H__ + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#endif /* __STDLIB_H__ */ + diff --git a/pxelinux/castor b/pxelinux/castor new file mode 100755 index 0000000..a61b9b5 Binary files /dev/null and b/pxelinux/castor differ diff --git a/pxelinux/castor.log b/pxelinux/castor.log new file mode 100644 index 0000000..0c5ccb7 --- /dev/null +++ b/pxelinux/castor.log @@ -0,0 +1,554 @@ +CPU Reset (CPU 0) +EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000 +ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000 +EIP=00000000 EFL=00000000 [-------] CPL=0 II=0 A20=0 SMM=0 HLT=0 +ES =0000 00000000 00000000 00000000 +CS =0000 00000000 00000000 00000000 +SS =0000 00000000 00000000 00000000 +DS =0000 00000000 00000000 00000000 +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00000000 +TR =0000 00000000 00000000 00000000 +GDT= 00000000 00000000 +IDT= 00000000 00000000 +CR0=00000000 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=0000000000000000 DR7=0000000000000000 +CCS=00000000 CCD=00000000 CCO=DYNAMIC +EFER=0000000000000000 +FCW=0000 FSW=0000 [ST=0] FTW=ff MXCSR=00000000 +FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 +FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 +FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 +FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 +XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 +XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 +XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 +XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 +CPU Reset (CPU 0) +EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000623 +ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000 +EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0000 00000000 0000ffff 00009300 +CS =f000 ffff0000 0000ffff 00009b00 +SS =0000 00000000 0000ffff 00009300 +DS =0000 00000000 0000ffff 00009300 +FS =0000 00000000 0000ffff 00009300 +GS =0000 00000000 0000ffff 00009300 +LDT=0000 00000000 0000ffff 00008200 +TR =0000 00000000 0000ffff 00008b00 +GDT= 00000000 0000ffff +IDT= 00000000 0000ffff +CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000000 CCD=00000000 CCO=DYNAMIC +EFER=0000000000000000 +FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80 +FPR0=0000000000000000 0000 FPR1=0000000000000000 0000 +FPR2=0000000000000000 0000 FPR3=0000000000000000 0000 +FPR4=0000000000000000 0000 FPR5=0000000000000000 0000 +FPR6=0000000000000000 0000 FPR7=0000000000000000 0000 +XMM00=00000000000000000000000000000000 XMM01=00000000000000000000000000000000 +XMM02=00000000000000000000000000000000 XMM03=00000000000000000000000000000000 +XMM04=00000000000000000000000000000000 XMM05=00000000000000000000000000000000 +XMM06=00000000000000000000000000000000 XMM07=00000000000000000000000000000000 +SMM: enter +EAX=00000001 EBX=0000000b ECX=02000000 EDX=00000cfc +ESI=00000000 EDI=02000000 EBP=00000000 ESP=00006d90 +EIP=000f1c59 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0008 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +GS =0010 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT +TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy +GDT= 000f6900 00000037 +IDT= 000f693e 00000000 +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=000f18e0 CCD=00000001 CCO=LOGICB +EFER=0000000000000000 +SMM: after RSM +EAX=00000001 EBX=0000000b ECX=02000000 EDX=00000cfc +ESI=00000000 EDI=02000000 EBP=00000000 ESP=00006d90 +EIP=000f1c59 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA] +CS =0008 00000000 ffffffff 00c09b00 DPL=0 CS32 [-RA] +SS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA] +DS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA] +FS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA] +GS =0010 00000000 ffffffff 00c09300 DPL=0 DS [-WA] +LDT=0000 00000000 0000ffff 00008200 DPL=0 LDT +TR =0000 00000000 0000ffff 00008b00 DPL=0 TSS32-busy +GDT= 000f6900 00000037 +IDT= 000f693e 00000000 +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000000 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 0: v=08 e=0000 i=0 cpl=0 IP=0020:000000000010554c pc=000000000010554c SP=0028:0000000000327c68 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000000 +ESI=00200000 EDI=00000000 EBP=00327c88 ESP=00327c68 +EIP=0010554c EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 1: v=08 e=0000 i=0 cpl=0 IP=0020:00000000001055a9 pc=00000000001055a9 SP=0028:0000000000327b5c EAX=0000000000000002 +EAX=00000002 EBX=001055a9 ECX=00000000 EDX=00000000 +ESI=00000000 EDI=00327c34 EBP=00327b6c ESP=00327b5c +EIP=001055a9 EFL=00000216 [----AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000014 CCD=00327b5c CCO=EFLAGS +EFER=0000000000000000 + 2: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00327c84 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 3: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 4: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 5: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 6: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 7: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 8: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 9: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 10: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 11: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 12: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 13: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 14: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 15: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 16: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 17: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 18: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 19: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 20: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000103027 pc=0000000000103027 SP=0028:0000000000327bb8 EAX=0000000000000000 +EAX=00000000 EBX=00110718 ECX=00000000 EDX=00000001 +ESI=00000000 EDI=000003e9 EBP=00000000 ESP=00327bb8 +EIP=00103027 EFL=00000246 [---Z-P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000044 CCD=00000000 CCO=EFLAGS +EFER=0000000000000000 + 21: v=08 e=0000 i=0 cpl=0 IP=0020:000000000010810b pc=000000000010810b SP=0028:0000000000327988 EAX=0000000000000000 +EAX=00000000 EBX=00000004 ECX=00000000 EDX=00000000 +ESI=00000032 EDI=0033bb70 EBP=003279f8 ESP=00327988 +EIP=0010810b EFL=00000216 [----AP-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000014 CCD=00327944 CCO=EFLAGS +EFER=0000000000000000 + 22: v=08 e=0000 i=0 cpl=0 IP=0020:0000000000104cb5 pc=0000000000104cb5 SP=0028:0000000000327a6b EAX=000000000000000d +EAX=0000000d EBX=00110718 ECX=00000001 EDX=07fc529c +ESI=00000063 EDI=0000000d EBP=0033fa90 ESP=00327a6b +EIP=00104cb5 EFL=00000212 [----A--] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0020 00000000 ffffffff 00cf9b00 DPL=0 CS32 [-RA] +SS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0028 00000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0000 00000000 00000000 00000000 +GS =0000 00000000 00000000 00000000 +LDT=0000 00000000 00000000 00008200 DPL=0 LDT +TR =0008 00000580 00000067 00008900 DPL=0 TSS32-avl +GDT= 00008a50 0000002f +IDT= 00003008 000007ff +CR0=00000011 CR2=00000000 CR3=00000000 CR4=00000000 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000010 CCD=0000000d CCO=EFLAGS +EFER=0000000000000000 +check_exception old: 0xffffffff new 0x6 + 23: v=06 e=0000 i=0 cpl=0 IP=0008:00000000004027b9 pc=00000000004027b9 SP=0010:000000000040dac0 EAX=00000000ffffffff +RAX=00000000ffffffff RBX=0000000000002000 RCX=0000000000000004 RDX=000000000000000d +RSI=0000000000000000 RDI=0000000000000000 RBP=0000000000000000 RSP=000000000040dac0 +R8 =00000000ffffffff R9 =0000000000000020 R10=0000000000000000 R11=0000000000000000 +R12=0000000000000000 R13=0000000000000000 R14=0000000000000000 R15=0000000000000000 +RIP=00000000004027b9 RFL=00000006 [-----P-] CPL=0 II=0 A20=1 SMM=0 HLT=0 +ES =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] +CS =0008 0000000000000000 ffffffff 00af9a00 DPL=0 CS64 [-R-] +SS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] +DS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] +FS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] +GS =0010 0000000000000000 ffffffff 00cf9300 DPL=0 DS [-WA] +LDT=0000 0000000000000000 00000000 00008200 DPL=0 LDT +TR =0020 0000000000409020 00000068 00008900 DPL=0 TSS64-avl +GDT= 0000000000409740 00000037 +IDT= 0000000000407020 00000fff +CR0=8005003b CR2=0000000000000000 CR3=0000000000404000 CR4=000006a0 +DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000 +DR6=00000000ffff0ff0 DR7=0000000000000400 +CCS=00000000000000d8 CCD=000000000040dab8 CCO=ADDQ +EFER=0000000000000d00 +qemu: terminating on signal 2 diff --git a/pxelinux/ldlinux.c32 b/pxelinux/ldlinux.c32 new file mode 100644 index 0000000..ccaf501 Binary files /dev/null and b/pxelinux/ldlinux.c32 differ diff --git a/pxelinux/libcom32.c32 b/pxelinux/libcom32.c32 new file mode 100644 index 0000000..2d6a736 Binary files /dev/null and b/pxelinux/libcom32.c32 differ diff --git a/pxelinux/libutil.c32 b/pxelinux/libutil.c32 new file mode 100644 index 0000000..46bd24a Binary files /dev/null and b/pxelinux/libutil.c32 differ diff --git a/pxelinux/mboot.c32 b/pxelinux/mboot.c32 new file mode 100644 index 0000000..ac5aa27 Binary files /dev/null and b/pxelinux/mboot.c32 differ diff --git a/pxelinux/menu.c32 b/pxelinux/menu.c32 new file mode 100644 index 0000000..7eb6060 Binary files /dev/null and b/pxelinux/menu.c32 differ diff --git a/pxelinux/pxelinux.0 b/pxelinux/pxelinux.0 new file mode 100644 index 0000000..fb05332 Binary files /dev/null and b/pxelinux/pxelinux.0 differ diff --git a/pxelinux/pxelinux.cfg/default b/pxelinux/pxelinux.cfg/default new file mode 100644 index 0000000..202b084 --- /dev/null +++ b/pxelinux/pxelinux.cfg/default @@ -0,0 +1,15 @@ +# D-I config version 2.0 +prompt 0 +timeout 10 +default menu.c32 + +menu margin 20 +menu width 80 +menu vshift 3 +menu title Main Menu + +label Castor + menu label Castor 64-bit + kernel mboot.c32 + append castor + diff --git a/pxelinux/run-castor b/pxelinux/run-castor new file mode 100755 index 0000000..b85648a --- /dev/null +++ b/pxelinux/run-castor @@ -0,0 +1,4 @@ +#!/bin/sh + +qemu-system-x86_64 -bootp tftp://10.0.2.2/pxelinux.0 -tftp ./ + diff --git a/pxelinux/run-castor-dbg b/pxelinux/run-castor-dbg new file mode 100755 index 0000000..40bc66a --- /dev/null +++ b/pxelinux/run-castor-dbg @@ -0,0 +1,4 @@ +#!/bin/sh + +qemu-system-x86_64 -d int,cpu_reset,guest_errors -bootp tftp://10.0.2.2/pxelinux.0 -tftp ./ + diff --git a/pxelinux/vesamenu.c32 b/pxelinux/vesamenu.c32 new file mode 100644 index 0000000..8eef0eb Binary files /dev/null and b/pxelinux/vesamenu.c32 differ diff --git a/sys/SConscript b/sys/SConscript new file mode 100644 index 0000000..78c8764 --- /dev/null +++ b/sys/SConscript @@ -0,0 +1,39 @@ +import sys + +Import('env') + +kern_env = env.Clone() + +src = [ ] + +src_amd64 = [ + # Multiboot requires multiboot.S to be the first file + "amd64/multiboot.S", + "amd64/mbentry.c", + # AMD64 + "amd64/trap.c", + "amd64/trapentry.S", + "amd64/machine.c", + "amd64/lapic.c", + "amd64/ioapic.c", + "dev/x86/vgacons.c", +] + +src_common = [ + "kern/libc.c", + "kern/palloc.c", + "kern/printf.c", +] + +if (env["ARCH"] == "amd64"): + src.append(src_amd64) + src.append(src_common) + +kern_env.Append(LINKFLAGS = ['-N', '-nostdlib']) +kern_env.Append(CPPFLAGS = ['-ffreestanding', '-fno-builtin', '-nostdinc', + '-mno-red-zone', '-mcmodel=kernel']) +# '-target', 'amd64-orion-eabi' +kern_env.Append(CPPPATH = ['#include', '#sys/include']) + +kern_env.Program("castor", src) + diff --git a/sys/amd64/amd64.h b/sys/amd64/amd64.h new file mode 100644 index 0000000..11b059c --- /dev/null +++ b/sys/amd64/amd64.h @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#ifndef __AMD64_H__ +#define __AMD64_H__ + +/* + * Page Tables + */ + +#define PGSHIFT 12 +#define PGSIZE (1 << PGSHIFT) +#define PGMASK (PGSIZE - 1) + +#define LARGE_PGSHIFT 21 +#define LARGE_PGSIZE (1 << LARGE_PGSHIFT) +#define LARGE_PGMASK (LARGE_PGSIZE - 1) + +#define ROUNDUP_PGSIZE(x) (((x) + PGSIZE - 1) & ~PGMASK) +#define ROUNDDOWN_PGSIZE(x) ((x) & ~PGMASK) + +#define PTE_P 0x0001 /* Present */ +#define PTE_W 0x0002 /* Writeable */ +#define PTE_U 0x0004 /* User */ +#define PTE_PWT 0x0008 /* Write Through */ +#define PTE_PCD 0x0010 /* Cache Disable */ +#define PTE_A 0x0020 /* Accessed */ +#define PTE_D 0x0040 /* Dirty */ +#define PTE_PS 0x0080 /* Page Size */ +#define PTE_G 0x0100 /* Global */ +#define PTE_OS1 0x0200 /* Available */ +#define PTE_OS2 0x0400 /* Available */ +#define PTE_OS3 0x0800 /* Available */ +#define PTE_PAT 0x1000 /* Page Attribute Table */ +#define PTE_NX 0x8000000000000000ULL /* No Execute */ + +typedef uint64_t PageEntry; + +typedef struct PageTable { + PageEntry entries[512]; +} PageTable; + +/* + * Global Descriptor Table + */ + +typedef struct PACKED PseudoDescriptor { + uint16_t lim; + uint64_t off; +} PseudoDescriptor; + +#define SEG_G +#define SEG_DB +#define SEG_L +#define SEG_P +#define SEG_DPL_SHIFT 45 +#define SEG_S + +#define SEG_CS (0xE << 40) +#define SEG_DS (0x2 << 40) + +#define SEG_TSA (0x9 << 40) +#define SEG_TSB (0xB << 40) + +#define SEL_KCS 0x08 +#define SEL_KDS 0x10 +#define SEL_TSS 0x20 +#define SEL_UCS 0x28 +#define SEL_UDS 0x30 + +typedef uint64_t SegmentDescriptor; + +/* + * Interrupt Descriptor Table + */ + +typedef struct PACKED InteruptGate64 { + uint16_t pc_low; + uint16_t cs; + uint8_t ist; + uint8_t type; + uint16_t pc_mid; + uint32_t pc_high; + uint32_t _unused1; +} InteruptGate64; + +/* + * Task State Segment + */ + +typedef struct PACKED TaskStateSegment64 { + uint16_t iomap_offset; + uint16_t _unused0; + uint32_t _unused1; + uint32_t _unused2; + uint64_t ist7; + uint64_t ist6; + uint64_t ist5; + uint64_t ist4; + uint64_t ist3; + uint64_t ist2; + uint64_t ist1; + uint64_t _unused3; + uint64_t rsp2; + uint64_t rsp1; + uint64_t rsp0; + uint32_t _unused4; +} TaskStateSegment64; + +/* + * Control Registers + */ + +#define CR0_PE 0x00000001 /* Protection Enabled */ +#define CR0_MP 0x00000002 /* Monitor Coprocessor */ +#define CR0_EM 0x00000004 /* Emulation */ +#define CR0_TS 0x00000008 /* Task Switched */ +#define CR0_ET 0x00000010 /* Extension Type */ +#define CR0_NE 0x00000020 /* Numeric Error */ +#define CR0_WP 0x00010000 /* Write Protect */ +#define CR0_AM 0x00040000 /* Alignment Mask */ +#define CR0_NW 0x20000000 /* Not Writethrough */ +#define CR0_CD 0x40000000 /* Cache Disable */ +#define CR0_PG 0x80000000 /* Paging */ + +#define CR4_VME 0x00000001 /* Virtual 8086 Mode Enable */ +#define CR4_PVI 0x00000002 /* Protected-Mode Virtual Interupts */ +#define CR4_TSD 0x00000004 /* Time Stamp Diable */ +#define CR4_DE 0x00000008 /* Debugging Extensions */ +#define CR4_PSE 0x00000010 /* Page Size Extensions */ +#define CR4_PAE 0x00000020 /* Physical Address Extension */ +#define CR4_MCE 0x00000040 /* Machine Check Enable */ +#define CR4_PGE 0x00000080 /* Page Global Enable */ +#define CR4_PCE 0x00000100 /* Performance Monitoring Counter Enable */ +#define CR4_OSFXSR 0x00000200 /* OS FXSAVE/FXRSTOR Support */ +#define CR4_OSXMMEXCPT 0x00000400 /* OS Unmasked Exception Support */ +#define CR4_FSGSBASE 0x00010000 /* Enable FS/GS read/write Instructions */ +#define CR4_OSXSAVE 0x00040000 /* XSAVE and Processor Extended States Enable */ + +#define RFLAGS_CF 0x00000001 /* Carry Flag */ +#define RFLAGS_PF 0x00000004 /* Parity Flag */ +#define RFLAGS_AF +#define RFLAGS_ZF +#define RFLAGS_SF +#define RFLAGS_TF +#define RFLAGS_IF +#define RFLAGS_DF +#define RFLAGS_OF +// IOPL +#define RFLAGS_NT + +#define RFLAGS_RF 0x00010000 +#define RFLAGS_VM 0x00020000 +#define RFLAGS_AC 0x00040000 +#define RFLAGS_VIF 0x00080000 +#define RFLAGS_VIP +#define RFLAGS_ID + +/* + * Debug Registers + */ + +/* + * MSRs + */ + +#define MSR_EFER 0xC0000080 + +#define EFER_SCE 0x0001 /* Syscall Enable */ +#define EFER_LME 0x0100 /* Long Mode Enable */ +#define EFER_LMA 0x0400 /* Long Mode Active */ +#define EFER_NXE 0x0800 /* Enable Execute Disable */ +#define EFER_SVME 0x1000 /* SVM Enable (AMD) */ +#define EFER_SLE 0x2000 /* Long Mode Segment Limit Enable (AMD) */ +#define EFER_FFXSR 0x4000 /* Fast FXSAVE/FXRSTOR (AMD) */ +#define EFER_TCE 0x8000 /* Translation Cache Extension (AMD) */ + +#include "amd64op.h" + +#endif /* __AMD64_H__ */ + diff --git a/sys/amd64/amd64op.h b/sys/amd64/amd64op.h new file mode 100644 index 0000000..068b2bf --- /dev/null +++ b/sys/amd64/amd64op.h @@ -0,0 +1,329 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#ifndef __AMD64OP_H__ +#define __AMD64OP_H__ + +static INLINE void enable_interrupts() +{ + asm volatile("sti"); +} + +static INLINE void disable_interrupts() +{ + asm volatile("cli"); +} + +static INLINE void hlt() +{ + asm volatile("hlt"); +} + +static INLINE void breakpoint() +{ + asm volatile("int3"); +} + +static INLINE void icebp() +{ + asm volatile(".byte 0xf1"); +} + +static INLINE void lidt(PseudoDescriptor *idt) +{ + asm volatile("lidt (%0)" + : + : "r" (idt) + : "memory"); +} + +static INLINE void lgdt(PseudoDescriptor *gdt) +{ + asm volatile("lgdt (%0)" + : + : "r" (gdt) + : "memory"); +} + +static INLINE void ltr(uint16_t tss) +{ + asm volatile("ltr %0" + : + : "r" (tss)); +} + +static INLINE void cpuid(uint32_t info, uint32_t *eax, uint32_t *ebx, + uint32_t *ecx, uint32_t *edx) +{ + uint32_t a, b, c, d; + + asm volatile("cpuid" + : "=a" (a), "=b" (b), "=c" (c), "=d" (d) + : "a" (info)); + + if (eax) + *eax = a; + if (ebx) + *ebx = b; + if (ecx) + *ecx = c; + if (edx) + *edx = d; +} + +static INLINE void wrmsr(uint32_t addr, uint64_t val) +{ + uint32_t eax = val & 0xFFFFFFFF; + uint32_t edx = val >> 32; + + asm volatile("wrmsr" + : + : "a" (eax), "c" (addr), "d" (edx)); +} + +static INLINE uint64_t rdmsr(uint32_t addr) +{ + uint64_t eax, edx; + + asm volatile("rdmsr" + : "=a" (eax), "=d" (edx) + : "c" (addr)); + + return edx << 32 | eax; +} + +static INLINE uint64_t read_cr0() +{ + uint64_t val; + + asm volatile("movq %%cr0, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_cr0(uint64_t val) +{ + asm volatile("movq %0, %%cr0" + : + : "r" (val)); +} + +static INLINE uint64_t read_cr2() +{ + uint64_t val; + + asm volatile("movq %%cr2, %0" + : "=r" (val)); + + return val; +} + +static INLINE uint64_t read_cr3() +{ + uint64_t val; + + asm volatile("movq %%cr3, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_cr3(uint64_t val) +{ + asm volatile("movq %0, %%cr3" + : + : "r" (val)); +} + +static INLINE uint64_t read_cr4() +{ + uint64_t val; + + asm volatile("movq %%cr4, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_cr4(uint64_t val) +{ + asm volatile("movq %0, %%cr4" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr0() +{ + uint64_t val; + + asm volatile("movq %%dr0, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr0(uint64_t val) +{ + asm volatile("movq %0, %%dr0" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr1() +{ + uint64_t val; + + asm volatile("movq %%dr1, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr1(uint64_t val) +{ + asm volatile("movq %0, %%dr1" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr2() +{ + uint64_t val; + + asm volatile("movq %%dr2, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr2(uint64_t val) +{ + asm volatile("movq %0, %%dr2" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr3() +{ + uint64_t val; + + asm volatile("movq %%dr3, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr3(uint64_t val) +{ + asm volatile("movq %0, %%dr3" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr6() +{ + uint64_t val; + + asm volatile("movq %%dr6, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr6(uint64_t val) +{ + asm volatile("movq %0, %%dr6" + : + : "r" (val)); +} + +static INLINE uint64_t read_dr7() +{ + uint64_t val; + + asm volatile("movq %%dr7, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_dr7(uint64_t val) +{ + asm volatile("movq %0, %%dr7" + : + : "r" (val)); +} + +static INLINE uint16_t read_ds() +{ + uint16_t val; + + asm volatile("movw %%ds, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_ds(uint16_t val) +{ + asm volatile("movw %0, %%ds" + : + : "r" (val)); +} + +static INLINE uint16_t read_es() +{ + uint16_t val; + + asm volatile("movw %%es, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_es(uint16_t val) +{ + asm volatile("movw %0, %%es" + : + : "r" (val)); +} + +static INLINE uint16_t read_fs() +{ + uint16_t val; + + asm volatile("movw %%fs, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_fs(uint16_t val) +{ + asm volatile("movw %0, %%fs" + : + : "r" (val)); +} + +static INLINE uint16_t read_gs() +{ + uint16_t val; + + asm volatile("movw %%gs, %0" + : "=r" (val)); + + return val; +} + +static INLINE void write_gs(uint16_t val) +{ + asm volatile("movw %0, %%gs" + : + : "r" (val)); +} + +#endif /* __AMD64OP_H__ */ + diff --git a/sys/amd64/asm.h b/sys/amd64/asm.h new file mode 100644 index 0000000..bbaf86e --- /dev/null +++ b/sys/amd64/asm.h @@ -0,0 +1,10 @@ +/* + * Assembly Macros + */ + +#define FUNC_BEGIN(fname) .p2align 4, 0x90; .global fname; \ + .type fname, @function; \ + fname: + +#define FUNC_END(fname) .size fname, . - fname + diff --git a/sys/amd64/ioapic.c b/sys/amd64/ioapic.c new file mode 100644 index 0000000..3e6960c --- /dev/null +++ b/sys/amd64/ioapic.c @@ -0,0 +1,76 @@ +/* + * IOAPIC + */ + +#include +#include + +#include "trap.h" + +#define IOAPICBASE 0xFEC00000 + +#define IOAPICID 0x00 /* IOAPIC ID */ +#define IOAPICVER 0x01 /* IOAPIC Version */ +#define IOAPICARB 0x02 /* IOAPIC Arbitration ID */ +#define IOREDTBL0 0x10 +#define IOREDTBL23 0x3E + +#define IOREDTBL_LEN 24 + +#define IOREDTBL_MASK 0x00010000 +#define IOREDTBL_LOGICAL 0x00000800 + +uint32_t +IOAPIC_Read(uint32_t reg) +{ + uint32_t volatile *addr = (uint32_t volatile *)IOAPICBASE; + uint32_t volatile *cmd = (uint32_t volatile *)(IOAPICBASE + 0x10); + + ASSERT(reg <= 0xFF); + + *addr = reg; + return *cmd; +} + +void +IOAPIC_Write(uint32_t reg, uint32_t val) +{ + uint32_t volatile *addr = (uint32_t volatile *)IOAPICBASE; + uint32_t volatile *cmd = (uint32_t volatile *)(IOAPICBASE + 0x10); + + ASSERT(reg <= 0xFF); + + *addr = reg; + *cmd = val; +} + +void +IOAPIC_Init() +{ + int i; + uint32_t id = (IOAPIC_Read(IOAPICID) >> 24) & 0x0F; + uint32_t maxInts = (IOAPIC_Read(IOAPICVER) >> 16) & 0xFF; + + kprintf("IOAPIC ID:%d Max Interrupts: %d\n", id, maxInts); + + for (i = 0; i <= IOREDTBL_LEN; i++) + { + IOAPIC_Write(IOREDTBL0 + 2*i, IOREDTBL_MASK | (T_IRQ_BASE + i)); + IOAPIC_Write(IOREDTBL0 + 2*i + 1, 0); + } +} + +void +IOAPIC_Enable(int irq) +{ + uint32_t val = IOAPIC_Read(IOREDTBL0 + 2*irq); + IOAPIC_Write(IOREDTBL0 + 2*irq, val & ~IOREDTBL_MASK); +} + +void +IOAPIC_Disable(int irq) +{ + uint32_t val = IOAPIC_Read(IOREDTBL0 + 2*irq); + IOAPIC_Write(IOREDTBL0 + 2*irq, val | IOREDTBL_MASK); +} + diff --git a/sys/amd64/lapic.c b/sys/amd64/lapic.c new file mode 100644 index 0000000..d6fc19a --- /dev/null +++ b/sys/amd64/lapic.c @@ -0,0 +1,123 @@ +/* + * LAPIC + */ + +#include +#include + +#include "amd64.h" +#include "amd64op.h" +#include "trap.h" + +#define CPUID_FLAG_APIC 0x100 + +#define IA32_APIC_BASE_MSR 0x1B +#define IA32_APIC_BASE_MSR_BSP 0x100 +#define IA32_APIC_BASE_MSR_ENABLE 0x800 + +#define LAPIC_ID 0x0020 /* CPU ID */ +#define LAPIC_VERSION 0x0030 /* Version */ +#define LAPIC_TPR 0x0080 /* Task Priority Register */ +#define LAPIC_EOI 0x00B0 /* End of Interrupt */ +#define LAPIC_SIV 0x00F0 /* Spurious Interrupt Vector */ +#define LAPIC_SIV_ENABLE 0x100 +#define LAPIC_ESR 0x0280 /* Error Status Register */ + +#define LAPIC_LVT_TIMER 0x0320 /* LVT Timer */ +#define LAPIC_LVT_TIMER_ONESHOT 0x00000000 +#define LAPIC_LVT_TIMER_PERIODIC 0x00020000 +#define LAPIC_LVT_TIMER_TSCDEADLINE 0x00040000 +#define LAPIC_LVT_THERMAL 0x0330 /* LVT Thermal Sensor */ +#define LAPIC_LVT_PMCR 0x0340 /* LVT Performance Monitoring Counter */ +#define LAPIC_LVT_LINT0 0x0350 /* LVT LINT0 */ +#define LAPIC_LVT_LINT1 0x0360 /* LVT LINT1 */ +#define LAPIC_LVT_ERROR 0x0370 /* Error Register */ +#define LAPIC_LVT_MASK 0x00010000 + +#define LAPIC_TICR 0x0380 /* Timer Initial Count Register */ +#define LAPIC_TCCR 0x0390 /* Timer Currnet Count Register */ +#define LAPIC_TDCR 0x03E0 /* Time Divide Configuration Register */ +#define LAPIC_TDCR_X1 0x000B /* Divide counts by 1 */ + +static uint32_t * +LAPIC_GetBase() +{ + uint64_t base = rdmsr(IA32_APIC_BASE_MSR) & 0xFFFFFFFFFFFFF000ULL; + + return (uint32_t *)base; +} + +uint32_t +LAPIC_Read(uint16_t reg) +{ + uint32_t volatile *lapic = (uint32_t volatile *) LAPIC_GetBase(); + + return lapic[reg >> 2]; +} + +void +LAPIC_Write(uint16_t reg, uint32_t val) +{ + uint32_t volatile *lapic = (uint32_t volatile *)LAPIC_GetBase(); + + lapic[reg >> 2] = val; + lapic[LAPIC_ID >> 2]; +} + +uint32_t +LAPIC_CPU() +{ + return LAPIC_Read(LAPIC_ID) >> 24; +} + +void +LAPIC_SendEOI() +{ + LAPIC_Write(LAPIC_EOI, 0); +} + +void +LAPIC_Periodic(uint64_t rate) +{ + LAPIC_Write(LAPIC_TDCR, LAPIC_TDCR_X1); + LAPIC_Write(LAPIC_LVT_TIMER, LAPIC_LVT_TIMER_PERIODIC | T_IRQ_TIMER); + LAPIC_Write(LAPIC_TICR, rate); +} + +void +LAPIC_Init() +{ + uint32_t edx; + uint64_t base; + + cpuid(1, NULL, NULL, NULL, &edx); + if ((edx & CPUID_FLAG_APIC) == 0) + Panic("APIC is required!\n"); + + // Enable LAPIC + base = rdmsr(IA32_APIC_BASE_MSR); + wrmsr(IA32_APIC_BASE_MSR, base | IA32_APIC_BASE_MSR_ENABLE); + + kprintf("CPU %d LAPIC found at 0x%016llx\n", LAPIC_CPU(), base); + + // Enable interrupts + LAPIC_Write(LAPIC_SIV, LAPIC_SIV_ENABLE | T_IRQ_SPURIOUS); + + LAPIC_Periodic(10000000); + + LAPIC_Write(LAPIC_LVT_LINT0, LAPIC_LVT_MASK); + LAPIC_Write(LAPIC_LVT_LINT1, LAPIC_LVT_MASK); + LAPIC_Write(LAPIC_LVT_ERROR, T_IRQ_ERROR); + + LAPIC_Write(LAPIC_ESR, 0); + LAPIC_Write(LAPIC_ESR, 0); + + LAPIC_SendEOI(); + + LAPIC_Write(LAPIC_TPR, 0); + + enable_interrupts(); +} + + + diff --git a/sys/amd64/machine.c b/sys/amd64/machine.c new file mode 100644 index 0000000..88c0d83 --- /dev/null +++ b/sys/amd64/machine.c @@ -0,0 +1,86 @@ + +#include + +#include +#include + +#include "amd64.h" + +extern void Trap_Init(); + +#define GDT_MAX 7 + +static SegmentDescriptor GDT[MAX_CPUS][GDT_MAX]; +static PseudoDescriptor GDTDescriptor[MAX_CPUS]; +static TaskStateSegment64 TSS[MAX_CPUS]; + +static char df_stack[4096]; + +void Machine_GDTInit() +{ + uint64_t offset; + uint64_t tmp; + + kprintf("Initializing GDT... "); // Caused pagefault?? + + GDT[0][0] = 0x0; + GDT[0][1] = 0x00AF9A000000FFFFULL; /* Kernel CS */ + GDT[0][2] = 0x00CF92000000FFFFULL; /* Kernel DS */ + GDT[5][1] = 0x00AFFA000000FFFFULL; /* User CS */ + GDT[6][2] = 0x00CFF2000000FFFFULL; /* User DS */ + + // TSS + GDT[0][3] = 0x0; /* TSS */ + GDT[0][4] = sizeof(TaskStateSegment64); + offset = (uint64_t)&TSS[0]; + tmp = offset & 0x00FFFFFF; + GDT[0][4] |= (tmp << 16); + tmp = offset & 0xFF000000; + GDT[0][4] |= (tmp << 56); + GDT[0][4] |= 0x89ULL << 40; + + GDTDescriptor[0].off = (uint64_t)&GDT[0]; + GDTDescriptor[0].lim = 8*GDT_MAX - 1; + + lgdt(&GDTDescriptor[0]); + + kprintf("Done!\n"); +} + +void Machine_TSSInit() +{ + kprintf("Initializing TSS... "); + + TSS[0]._unused0 = 0; + TSS[0]._unused1 = 0; + TSS[0]._unused2 = 0; + TSS[0]._unused3 = 0; + TSS[0]._unused4 = 0; + TSS[0].ist1 = &df_stack; + TSS[0].rsp0 = 0; + TSS[0].rsp1 = 0; + TSS[0].rsp2 = 0; + + ltr(SEL_TSS); + + kprintf("Done!\n"); +} + +void Machine_SyscallInit() +{ + kprintf("Initializing Syscall... "); + + kprintf("Done!\n"); +} + +void Machine_Init() +{ + Machine_GDTInit(); + Machine_TSSInit(); + Trap_Init(); + //Machine_SyscallInit(); + + LAPIC_Init(); + IOAPIC_Init(); +} + diff --git a/sys/amd64/mbentry.c b/sys/amd64/mbentry.c new file mode 100644 index 0000000..f1287a8 --- /dev/null +++ b/sys/amd64/mbentry.c @@ -0,0 +1,214 @@ +/* + * Multiboot C Entry + */ + +#include + +#include +#include + +#include "../dev/console.h" + +#include "amd64.h" +#include "multiboot.h" + +extern void *_end; + +void mbentry(unsigned long magic, unsigned long addr); + +#define CHECK_FLAG(flag, bit) ((flag) & (1 << (bit))) + +#define PAGE_ALIGN __attribute__((aligned(PGSIZE))) +#define DATA_SECTION __attribute__((section(".data"))) + +extern void Machine_Init(); +extern void PAlloc_Init(); +extern void PAlloc_AddRegion(uintptr_t start, uintptr_t len); + +#define GENTBL_2(base) (base + 0x183), (base + 0x200183), +#define GENTBL_8(base) GENTBL_2(base) GENTBL_2(base + 0x400000) \ + GENTBL_2(base + 0x800000) GENTBL_2(base + 0xC00000) +#define GENTBL_32(base) GENTBL_8(base) GENTBL_8(base + 0x1000000) \ + GENTBL_8(base + 0x2000000) GENTBL_8(base + 0x3000000) +#define GENTBL_128(base) GENTBL_32(base) GENTBL_32(base + 0x4000000) \ + GENTBL_32(base + 0x8000000) GENTBL_32(base + 0xC000000) +#define GENTBL(base) GENTBL_128(base) GENTBL_128(base + 0x10000000) \ + GENTBL_128(base + 0x20000000) GENTBL_128(base + 0x30000000) + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3a = { .entries = { + GENTBL(0x0) +}}; + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3b = { .entries = { + GENTBL(0x40000000) +}}; + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3c = { .entries = { + GENTBL(0x80000000) +}}; + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl3d = { .entries = { + GENTBL(0xC0000000) +}}; + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl2 = { .entries = { + (uint64_t)&bootpgtbl3a + 0x03, + (uint64_t)&bootpgtbl3b + 0x03, + (uint64_t)&bootpgtbl3c + 0x03, + (uint64_t)&bootpgtbl3d + 0x03, + 0 +}}; + +PAGE_ALIGN DATA_SECTION PageTable bootpgtbl1 = { .entries = { + (uint64_t)&bootpgtbl2 + 0x03, + 0 +}}; + +void +mb_entry(unsigned long magic, unsigned long addr) +{ + multiboot_info_t *mbi = (multiboot_info_t *)addr; + + Console_Init(); + PAlloc_Init(); + + /* @r{Am I booted by a Multiboot-compliant boot loader?} */ + if (magic != MULTIBOOT_BOOTLOADER_MAGIC) + { + kprintf("Invalid magic number: 0x%x\n", magic); + //return; + } + + /* @r{Print out the flags.} */ + kprintf("flags = 0x%x\n", (uint64_t) mbi->flags); + + /* @r{Are mem_* valid?} */ + if (CHECK_FLAG (mbi->flags, 0)) + kprintf("mem_lower = %uKB, mem_upper = %uKB\n", + (unsigned) mbi->mem_lower, (unsigned) mbi->mem_upper); + + /* @r{Is boot_device valid?} */ + if (CHECK_FLAG (mbi->flags, 1)) + kprintf("boot_device = 0x%x\n", (unsigned) mbi->boot_device); + + /* @r{Is the command line passed?} */ + if (CHECK_FLAG (mbi->flags, 2)) + kprintf("cmdline = %s\n", (char *)(uintptr_t)mbi->cmdline); + + /* @r{Are mods_* valid?} */ + if (CHECK_FLAG (mbi->flags, 3)) + { + multiboot_module_t *mod; + int i; + + kprintf("mods_count = %d, mods_addr = 0x%x\n", + (int) mbi->mods_count, (int) mbi->mods_addr); + for (i = 0, mod = (multiboot_module_t *)(uintptr_t)mbi->mods_addr; + i < mbi->mods_count; + i++, mod++) + kprintf(" mod_start = 0x%x, mod_end = 0x%x, cmdline = %s\n", + (unsigned) mod->mod_start, + (unsigned) mod->mod_end, + (char *)(uintptr_t) mod->cmdline); + } + + /* @r{Bits 4 and 5 are mutually exclusive!} */ + if (CHECK_FLAG (mbi->flags, 4) && CHECK_FLAG (mbi->flags, 5)) + { + kprintf("Both bits 4 and 5 are set.\n"); + return; + } + + /* @r{Is the symbol table of a.out valid?} */ + if (CHECK_FLAG (mbi->flags, 4)) + { + multiboot_aout_symbol_table_t *multiboot_aout_sym = &(mbi->u.aout_sym); + + kprintf("multiboot_aout_symbol_table: tabsize = 0x%0x\n" + " strsize = 0x%x, addr = 0x%x\n", + (unsigned) multiboot_aout_sym->tabsize, + (unsigned) multiboot_aout_sym->strsize, + (unsigned) multiboot_aout_sym->addr); + } + + /* @r{Is the section header table of ELF valid?} */ + if (CHECK_FLAG (mbi->flags, 5)) + { + multiboot_elf_section_header_table_t *multiboot_elf_sec = &(mbi->u.elf_sec); + + kprintf("multiboot_elf_sec: num = %u, size = 0x%x," + " addr = 0x%x, shndx = 0x%x\n", + (unsigned) multiboot_elf_sec->num, (unsigned) multiboot_elf_sec->size, + (unsigned) multiboot_elf_sec->addr, (unsigned) multiboot_elf_sec->shndx); + } + + /* @r{Are mmap_* valid?} */ + if (CHECK_FLAG (mbi->flags, 6)) + { + multiboot_memory_map_t *mmap; + + kprintf("mmap_addr = 0x%x, mmap_length = 0x%x\n", + (unsigned) mbi->mmap_addr, (unsigned) mbi->mmap_length); + for (mmap = (multiboot_memory_map_t *)(uintptr_t) mbi->mmap_addr; + (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + + mmap->size + sizeof (mmap->size))) + { + kprintf(" size = 0x%x, base_addr = 0x%x," + " length = 0x%x, type = 0x%x\n", + (unsigned) mmap->size, + mmap->addr, + mmap->len, + (unsigned) mmap->type); + } + } + + Machine_Init(); + + uint64_t memoryStart = (uintptr_t)&_end; + + PAlloc_Init(); + + /* @r{Are mmap_* valid?} */ + if (CHECK_FLAG (mbi->flags, 6)) + { + multiboot_memory_map_t *mmap; + + for (mmap = (multiboot_memory_map_t *)(uintptr_t) mbi->mmap_addr; + (unsigned long) mmap < mbi->mmap_addr + mbi->mmap_length; + mmap = (multiboot_memory_map_t *) ((unsigned long) mmap + + mmap->size + sizeof (mmap->size))) + { + if (mmap->type == MULTIBOOT_MEMORY_AVAILABLE) { + kprintf(" size = 0x%x, base_addr = 0x%x," + " length = 0x%x, type = 0x%x\n", + (unsigned) mmap->size, + mmap->addr, + mmap->len, + (unsigned) mmap->type); + uintptr_t start = mmap->addr; + uintptr_t len = mmap->len; + + if (start + len > memoryStart) + { + if (start < memoryStart) + { + len = len - (memoryStart - start); + start = memoryStart; + } + + if ((start % PGSIZE) != 0) + { + len = len - (PGSIZE - (start & PGMASK)); + start = ROUNDUP_PGSIZE(start); + } + + len = ROUNDDOWN_PGSIZE(len); + + PAlloc_AddRegion(start, len); + } + } + } + } +} + diff --git a/sys/amd64/multiboot.S b/sys/amd64/multiboot.S new file mode 100644 index 0000000..cbcffc7 --- /dev/null +++ b/sys/amd64/multiboot.S @@ -0,0 +1,117 @@ +/* + * Multiboot Entry + */ + +#define STACK_SIZE 0x4000 + +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 +#define MULTIBOOT_HEADER_FLAGS 0x00010003 + +.extern mb_entry + +.text + +.globl _start +_start: .code32 + jmp multiboot_entry + +.align 4 +multiboot_header: .code32 +.long MULTIBOOT_HEADER_MAGIC +.long MULTIBOOT_HEADER_FLAGS +.long -(MULTIBOOT_HEADER_MAGIC + MULTIBOOT_HEADER_FLAGS) +.long multiboot_header +.long _start +.long _edata +.long _end +.long multiboot_entry + +// +// Multiboot entry +// %eax: Magic (0x2BADB002) +// %ebx: multiboot info structure +// +multiboot_entry: .code32 + movl %eax, %edx // Save multiboot magic + + movl $(lmfarptr), %edi + movw $(0x7000 + 'A'), (0xB8000) + movl $(stack + STACK_SIZE), %esp + + movw $(0x7000 + 'B'), (0xB8002) + pushl $0 + popf + + movw $(0x7000 + 'C'), (0xB8004) + movl %cr4, %eax + orl $0x0000006A0, %eax + movl %eax, %cr4 + + movw $(0x7000 + 'D'), (0xB8006) + movl $bootpgtbl1, %eax + movl %eax, %cr3 + + movw $(0x7000 + 'E'), (0xB8008) + movl $0xC0000080, %ecx + rdmsr + orl $0x0900, %eax + wrmsr + + movw $(0x7000 + 'E'), (0xB800A) + movl $bootgdtdesc, %eax + lgdt (%eax) + + movw $(0x7000 + 'F'), (0xB800C) + movl %cr0, %eax + orl $0x8005002B, %eax + movl %eax, %cr0 + + movw $(0x7000 + '0'), (0xB800E) + ljmp *(%edi) + +lmenter: .code64 + movw $(0x7000 + '1'), (0xB8010) + movw $0x10, %ax + movw %ax, %ss + movw %ax, %ds + movw %ax, %es + movw %ax, %fs + movw %ax, %gs + + movw $(0x7000 + '2'), (0xB8012) + + movq %rdx, %rdi // Magic + movq %rbx, %rsi // Multiboot info pointer + + call mb_entry + + movw $(0x5000 + 'H'), (0xB8098) + movw $(0x5000 + 'A'), (0xB809A) + movw $(0x5000 + 'L'), (0xB809C) + movw $(0x5000 + 'T'), (0xB809E) +loop: + hlt + jmp loop + +lmfarptr: +.long lmenter +.word 0x08 + +.p2align 12 +bootgdt: +.quad 0x0000000000000000 /* Null */ +.quad 0x00AF9A000000FFFF /* Kernel CS */ +.quad 0x00CF92000000FFFF /* Kernel DS */ +.quad 0x0000000000000000 +.quad 0x0000000000000000 +.quad 0x0000000000000000 +.quad 0x0000000000000000 + +.p2align 4 +bootgdtdesc: +.word 0x0040 +.quad bootgdt + +// Boot stack +.comm stack, STACK_SIZE + diff --git a/sys/amd64/multiboot.h b/sys/amd64/multiboot.h new file mode 100644 index 0000000..c7c4a40 --- /dev/null +++ b/sys/amd64/multiboot.h @@ -0,0 +1,265 @@ +/* multiboot.h - Multiboot header file. */ +/* Copyright (C) 1999,2003,2007,2008,2009,2010 Free Software Foundation, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ANY + * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR + * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MULTIBOOT_HEADER +#define MULTIBOOT_HEADER 1 + +/* How many bytes from the start of the file we search for the header. */ +#define MULTIBOOT_SEARCH 8192 +#define MULTIBOOT_HEADER_ALIGN 4 + +/* The magic field should contain this. */ +#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 + +/* This should be in %eax. */ +#define MULTIBOOT_BOOTLOADER_MAGIC 0x2BADB002 + +/* Alignment of multiboot modules. */ +#define MULTIBOOT_MOD_ALIGN 0x00001000 + +/* Alignment of the multiboot info structure. */ +#define MULTIBOOT_INFO_ALIGN 0x00000004 + +/* Flags set in the 'flags' member of the multiboot header. */ + +/* Align all boot modules on i386 page (4KB) boundaries. */ +#define MULTIBOOT_PAGE_ALIGN 0x00000001 + +/* Must pass memory information to OS. */ +#define MULTIBOOT_MEMORY_INFO 0x00000002 + +/* Must pass video information to OS. */ +#define MULTIBOOT_VIDEO_MODE 0x00000004 + +/* This flag indicates the use of the address fields in the header. */ +#define MULTIBOOT_AOUT_KLUDGE 0x00010000 + +/* Flags to be set in the 'flags' member of the multiboot info structure. */ + +/* is there basic lower/upper memory information? */ +#define MULTIBOOT_INFO_MEMORY 0x00000001 +/* is there a boot device set? */ +#define MULTIBOOT_INFO_BOOTDEV 0x00000002 +/* is the command-line defined? */ +#define MULTIBOOT_INFO_CMDLINE 0x00000004 +/* are there modules to do something with? */ +#define MULTIBOOT_INFO_MODS 0x00000008 + +/* These next two are mutually exclusive */ + +/* is there a symbol table loaded? */ +#define MULTIBOOT_INFO_AOUT_SYMS 0x00000010 +/* is there an ELF section header table? */ +#define MULTIBOOT_INFO_ELF_SHDR 0X00000020 + +/* is there a full memory map? */ +#define MULTIBOOT_INFO_MEM_MAP 0x00000040 + +/* Is there drive info? */ +#define MULTIBOOT_INFO_DRIVE_INFO 0x00000080 + +/* Is there a config table? */ +#define MULTIBOOT_INFO_CONFIG_TABLE 0x00000100 + +/* Is there a boot loader name? */ +#define MULTIBOOT_INFO_BOOT_LOADER_NAME 0x00000200 + +/* Is there a APM table? */ +#define MULTIBOOT_INFO_APM_TABLE 0x00000400 + +/* Is there video information? */ +#define MULTIBOOT_INFO_VBE_INFO 0x00000800 +#define MULTIBOOT_INFO_FRAMEBUFFER_INFO 0x00001000 + +struct multiboot_header +{ + /* Must be MULTIBOOT_MAGIC - see above. */ + uint32_t magic; + + /* Feature flags. */ + uint32_t flags; + + /* The above fields plus this one must equal 0 mod 2^32. */ + uint32_t checksum; + + /* These are only valid if MULTIBOOT_AOUT_KLUDGE is set. */ + uint32_t header_addr; + uint32_t load_addr; + uint32_t load_end_addr; + uint32_t bss_end_addr; + uint32_t entry_addr; + + /* These are only valid if MULTIBOOT_VIDEO_MODE is set. */ + uint32_t mode_type; + uint32_t width; + uint32_t height; + uint32_t depth; +}; + +/* The symbol table for a.out. */ +struct multiboot_aout_symbol_table +{ + uint32_t tabsize; + uint32_t strsize; + uint32_t addr; + uint32_t reserved; +}; +typedef struct multiboot_aout_symbol_table multiboot_aout_symbol_table_t; + +/* The section header table for ELF. */ +struct multiboot_elf_section_header_table +{ + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; +}; +typedef struct multiboot_elf_section_header_table multiboot_elf_section_header_table_t; + +struct multiboot_info +{ + /* Multiboot info version number */ + uint32_t flags; + + /* Available memory from BIOS */ + uint32_t mem_lower; + uint32_t mem_upper; + + /* "root" partition */ + uint32_t boot_device; + + /* Kernel command line */ + uint32_t cmdline; + + /* Boot-Module list */ + uint32_t mods_count; + uint32_t mods_addr; + + union + { + multiboot_aout_symbol_table_t aout_sym; + multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + uint32_t mmap_length; + uint32_t mmap_addr; + + /* Drive Info buffer */ + uint32_t drives_length; + uint32_t drives_addr; + + /* ROM configuration table */ + uint32_t config_table; + + /* Boot Loader Name */ + uint32_t boot_loader_name; + + /* APM table */ + uint32_t apm_table; + + /* Video */ + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; + + uint64_t framebuffer_addr; + uint32_t framebuffer_pitch; + uint32_t framebuffer_width; + uint32_t framebuffer_height; + uint8_t framebuffer_bpp; +#define MULTIBOOT_FRAMEBUFFER_TYPE_INDEXED 0 +#define MULTIBOOT_FRAMEBUFFER_TYPE_RGB 1 +#define MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT 2 + uint8_t framebuffer_type; + union + { + struct + { + uint32_t framebuffer_palette_addr; + uint16_t framebuffer_palette_num_colors; + }; + struct + { + uint8_t framebuffer_red_field_position; + uint8_t framebuffer_red_mask_size; + uint8_t framebuffer_green_field_position; + uint8_t framebuffer_green_mask_size; + uint8_t framebuffer_blue_field_position; + uint8_t framebuffer_blue_mask_size; + }; + }; +}; +typedef struct multiboot_info multiboot_info_t; + +struct multiboot_color +{ + uint8_t red; + uint8_t green; + uint8_t blue; +}; + +struct multiboot_mmap_entry +{ + uint32_t size; + uint64_t addr; + uint64_t len; +#define MULTIBOOT_MEMORY_AVAILABLE 1 +#define MULTIBOOT_MEMORY_RESERVED 2 +#define MULTIBOOT_MEMORY_ACPI_RECLAIMABLE 3 +#define MULTIBOOT_MEMORY_NVS 4 +#define MULTIBOOT_MEMORY_BADRAM 5 + uint32_t type; +} __attribute__((packed)); +typedef struct multiboot_mmap_entry multiboot_memory_map_t; + +struct multiboot_mod_list +{ + /* the memory used goes from bytes 'mod_start' to 'mod_end-1' inclusive */ + uint32_t mod_start; + uint32_t mod_end; + + /* Module command line */ + uint32_t cmdline; + + /* padding to take it to 16 bytes (must be zero) */ + uint32_t pad; +}; +typedef struct multiboot_mod_list multiboot_module_t; + +/* APM BIOS info. */ +struct multiboot_apm_info +{ + uint16_t version; + uint16_t cseg; + uint32_t offset; + uint16_t cseg_16; + uint16_t dseg; + uint16_t flags; + uint16_t cseg_len; + uint16_t cseg_16_len; + uint16_t dseg_len; +}; + +#endif /* ! MULTIBOOT_HEADER */ diff --git a/sys/amd64/trap.c b/sys/amd64/trap.c new file mode 100644 index 0000000..17abeae --- /dev/null +++ b/sys/amd64/trap.c @@ -0,0 +1,127 @@ + +#include + +#include +#include + +#include "amd64.h" +#include "trap.h" + +extern uint64_t trap_table[T_MAX]; +extern void trap_pop(TrapFrame *tf); + +static InteruptGate64 idt[256]; +static PseudoDescriptor idtdesc; + +void +Trap_Init() +{ + int i; + + kprintf("Initializing IDT... "); + + for (i = 0; i < T_MAX; i++) { + idt[i].pc_low = trap_table[i] & 0x0000ffff; + idt[i].pc_mid = (trap_table[i] >> 16) & 0x0000ffff; + idt[i].pc_high = trap_table[i] >> 32; + + idt[i].cs = 0x0008; + idt[i].type = 0x8E; + + idt[i].ist = 0x00; + idt[i]._unused1 = 0x00000000; + } + + for (; i < 256; i++) { + idt[i].pc_low = 0; + idt[i].pc_mid = 0; + idt[i].pc_high = 0; + idt[i].cs = 0; + idt[i].type = 0; + idt[i].ist = 0; + idt[i]._unused1 = 0; + } + + // Double fault handler + idt[T_DF].ist = 0x01; + + idtdesc.off = (uint64_t)&idt; + idtdesc.lim = sizeof(idt) - 1; + + lidt(&idtdesc); + + kprintf("Done!\n"); +} + +void +trap_dump(TrapFrame *tf) +{ + kprintf("Interrupt %d Error Code: %016llx\n", + tf->vector, tf->errcode); + kprintf("cr0: %016llx cr2: %016llx\n", + read_cr0(), read_cr2()); + kprintf("cr3: %016llx cr4: %016llx\n", + read_cr3(), read_cr4()); + kprintf("dr0: %016llx dr1: %016llx dr2: %016llx\n", + read_dr0(), read_dr1(), read_dr2()); + kprintf("dr3: %016llx dr6: %016llx dr7: %016llx\n", + read_dr3(), read_dr6(), read_dr7()); + kprintf("rip: %04x:%016x rsp: %04x:%016x\n", + tf->cs, tf->rip, tf->ss, tf->rsp); + kprintf("rflags: %016x ds: %04x es: %04x fs: %04x gs: %04x\n", + tf->rflags, read_ds(), read_es(), read_fs(), read_gs()); + kprintf("rax: %016llx rbx: %016llx rcx: %016llx\n", + tf->rax, tf->rbx, tf->rcx); + kprintf("rdx: %016llx rsi: %016llx rdi: %016llx\n", + tf->rdx, tf->rsi, tf->rdi); + kprintf("rbp: %016llx r8: %016llx r9: %016llx\n", + tf->rbp, tf->r8, tf->r9); + kprintf("r10: %016llx r11: %016llx r12: %016llx\n", + tf->r10, tf->r11, tf->r12); + kprintf("r13: %016llx r14: %016llx r15: %016llx\n", + tf->r13, tf->r14, tf->r15); +} + +void +trap_entry(TrapFrame *tf) +{ + // Halt on kernel errors + if (tf->vector <= T_CPU_LAST && tf->cs == SEL_KCS) + { + trap_dump(tf); + + while (1) + hlt(); + } + + switch (tf->vector) + { + case T_DE: + break; + case T_DB: + case T_BP: + break; + case T_UD: + case T_DF: + break; + default: + break; + } + + if (tf->vector >= T_IRQ_BASE && tf->vector <= T_IRQ_MAX) + { + kprintf("IRQ: %d\n", tf->vector); + LAPIC_SendEOI(); + return; + } + + if (tf->vector == T_IRQ_SPURIOUS) + { + kprintf("Spurious interrupt!"); + LAPIC_SendEOI(); + } + trap_dump(tf); + + while (1) { } +} + diff --git a/sys/amd64/trap.h b/sys/amd64/trap.h new file mode 100644 index 0000000..8a9e2fd --- /dev/null +++ b/sys/amd64/trap.h @@ -0,0 +1,74 @@ + +#ifndef __TRAP_H__ +#define __TRAP_H__ + +#define T_DE 0 +#define T_DB 1 +#define T_NMI 2 +#define T_BP 3 +#define T_OF 4 +#define T_BR 5 +#define T_UD 6 +#define T_NM 7 +#define T_DF 8 +#define T_TS 10 +#define T_NP 11 +#define T_SS 12 +#define T_GP 13 +#define T_PF 14 +#define T_MF 16 +#define T_AC 17 +#define T_MC 18 +#define T_XF 19 +#define T_VE 20 + +#define T_CPU_LAST T_VE + +#define T_IRQ_BASE 32 +#define T_IRQ_LEN 24 +#define T_IRQ_MAX (T_IRQ_BASE + T_IRQ_LEN - 1) + +#define T_IRQ_TIMER (T_IRQ_BASE + 0) +#define T_IRQ_KBD (T_IRQ_BASE + 1) +#define T_IRQ_COM1 (T_IRQ_BASE + 4) +#define T_IRQ_SPURIOUS (T_IRQ_BASE + 24) +#define T_IRQ_ERROR (T_IRQ_BASE + 25) + +#define T_MAX 64 + +typedef struct TrapFrame +{ + uint64_t r15; + uint64_t r14; + uint64_t r13; + uint64_t r12; + uint64_t r11; + uint64_t r10; + uint64_t r9; + uint64_t r8; + uint64_t rbp; + uint64_t rdi; + uint64_t rsi; + uint64_t rdx; + uint64_t rcx; + uint64_t rbx; + uint64_t rax; + + uint64_t vector; + uint32_t errcode; + uint32_t _unused0; + uint64_t rip; + uint16_t cs; + uint16_t _unused1; + uint16_t _unused2; + uint16_t _unused3; + uint64_t rflags; + uint64_t rsp; + uint16_t ss; + uint16_t _unused4; + uint16_t _unused5; + uint16_t _unused6; +} TrapFrame; + +#endif /* __TRAP_H__ */ + diff --git a/sys/amd64/trapentry.S b/sys/amd64/trapentry.S new file mode 100644 index 0000000..7107ee3 --- /dev/null +++ b/sys/amd64/trapentry.S @@ -0,0 +1,196 @@ +/* + * Trap Handlers + */ + +.extern trap_entry + +.text + +.macro TRAP_NOEC TRAPNUM +trap\TRAPNUM: + pushq %rax + pushq $\TRAPNUM + pushq %rax + jmp trap_common +.endm + +.macro TRAP_EC TRAPNUM +trap\TRAPNUM: + pushq $\TRAPNUM + pushq %rax + jmp trap_common +.endm + +.globl trap_table +trap_table: +.quad trap0 +.quad trap1 +.quad trap2 +.quad trap3 +.quad trap4 +.quad trap5 +.quad trap6 +.quad trap7 +.quad trap8 +.quad trap9 +.quad trap10 +.quad trap11 +.quad trap12 +.quad trap13 +.quad trap14 +.quad trap15 +.quad trap16 +.quad trap17 +.quad trap18 +.quad trap19 +.quad trap20 +.quad trap21 +.quad trap22 +.quad trap23 +.quad trap24 +.quad trap25 +.quad trap26 +.quad trap27 +.quad trap28 +.quad trap29 +.quad trap30 +.quad trap31 +.quad trap32 +.quad trap33 +.quad trap34 +.quad trap35 +.quad trap36 +.quad trap37 +.quad trap38 +.quad trap39 +.quad trap40 +.quad trap41 +.quad trap42 +.quad trap43 +.quad trap44 +.quad trap45 +.quad trap46 +.quad trap47 +.quad trap48 +.quad trap49 +.quad trap50 +.quad trap51 +.quad trap52 +.quad trap53 +.quad trap54 +.quad trap55 +.quad trap56 +.quad trap57 +.quad trap58 +.quad trap59 +.quad trap60 +.quad trap61 +.quad trap62 +.quad trap63 + +TRAP_NOEC 0 // DE +TRAP_NOEC 1 // DB +TRAP_NOEC 2 // NMI +TRAP_NOEC 3 // BP +TRAP_NOEC 4 // OF +TRAP_NOEC 5 // BR +TRAP_NOEC 6 // UD +TRAP_NOEC 7 // NM +TRAP_EC 8 // DF +TRAP_NOEC 9 +TRAP_EC 10 // TS +TRAP_EC 11 // NP +TRAP_EC 12 // SS +TRAP_EC 13 // GP +TRAP_EC 14 // PF +TRAP_NOEC 15 +TRAP_NOEC 16 // MF +TRAP_EC 17 // AC +TRAP_NOEC 18 // MC +TRAP_NOEC 19 // XF +TRAP_NOEC 20 // VE +TRAP_NOEC 21 +TRAP_NOEC 22 +TRAP_NOEC 23 +TRAP_NOEC 24 +TRAP_NOEC 25 +TRAP_NOEC 26 +TRAP_NOEC 27 +TRAP_NOEC 28 +TRAP_NOEC 29 +TRAP_NOEC 30 +TRAP_NOEC 31 +TRAP_NOEC 32 // IRQ 0 +TRAP_NOEC 33 +TRAP_NOEC 34 +TRAP_NOEC 35 +TRAP_NOEC 36 +TRAP_NOEC 37 +TRAP_NOEC 38 +TRAP_NOEC 39 +TRAP_NOEC 40 +TRAP_NOEC 41 +TRAP_NOEC 42 +TRAP_NOEC 43 +TRAP_NOEC 44 +TRAP_NOEC 45 +TRAP_NOEC 46 +TRAP_NOEC 47 // IRQ 15 +TRAP_NOEC 48 // IRQ 16 (PCI) +TRAP_NOEC 49 +TRAP_NOEC 50 +TRAP_NOEC 51 +TRAP_NOEC 52 +TRAP_NOEC 53 +TRAP_NOEC 54 +TRAP_NOEC 55 // IRQ 23 (PCI) +TRAP_NOEC 56 // IPIs +TRAP_NOEC 57 +TRAP_NOEC 58 +TRAP_NOEC 59 +TRAP_NOEC 60 +TRAP_NOEC 61 +TRAP_NOEC 62 +TRAP_NOEC 63 + +trap_common: + pushq %rbx + pushq %rcx + pushq %rdx + pushq %rsi + pushq %rdi + pushq %rbp + pushq %r8 + pushq %r9 + pushq %r10 + pushq %r11 + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 + movq %rsp, %rdi + call trap_entry +trap_return: + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %r11 + popq %r10 + popq %r9 + popq %r8 + popq %rbp + popq %rdi + popq %rsi + popq %rdx + popq %rcx + popq %rbx + popq %rax + addq $16, %rsp // Skip error code and vector number + iretq + +.globl trap_pop +trap_pop: + movq %rdi, %rsp + jmp trap_return + diff --git a/sys/dev/console.h b/sys/dev/console.h new file mode 100644 index 0000000..918c710 --- /dev/null +++ b/sys/dev/console.h @@ -0,0 +1,14 @@ + +#ifndef __CONSOLE_H__ +#define __CONSOLE_H__ + +#include "x86/vgacons.h" + +// Placeholder until a proper console driver is made + +#define Console_Init VGA_Init +#define Console_Putc VGA_Putc +#define Console_Puts VGA_Puts + +#endif /* __CONSOLE_H__ */ + diff --git a/sys/dev/x86/ioport.h b/sys/dev/x86/ioport.h new file mode 100644 index 0000000..2c95cc2 --- /dev/null +++ b/sys/dev/x86/ioport.h @@ -0,0 +1,101 @@ +/* + * HyperKernel - kernel/arch/x86/cpufunc.h + * Copyright (c) 2006-2007 Mashtizadeh Corporation + * All rights reserved. + * + */ + +#include + +static __inline__ unsigned char inb(unsigned short port) +{ + unsigned char retval; + __asm__ __volatile__ ("inb %w1, %0\n\t" + : "=a" (retval) + : "d" (port)); + return retval; +} + +static __inline__ unsigned short inw(unsigned short port) +{ + unsigned short retval; + __asm__ __volatile__ ("inw %w1, %0\n\t" + : "=a" (retval) + : "d" (port)); + return retval; +} + +static __inline__ unsigned int inl(int port) +{ + unsigned int retval; + __asm__ __volatile__ ("inl %w1, %0\n\t" + : "=a" (retval) + : "d" (port)); + return retval; +} + +static __inline__ void outb(int port, unsigned char val) +{ + __asm__ __volatile__ ("outb %0, %w1\n\t" + : + : "a" (val), + "d" (port)); +} + +static __inline__ void outw(int port, unsigned short val) +{ + __asm__ __volatile__ ("outw %0, %w1\n\t" + : + : "a" (val), + "d" (port)); +} + +static __inline__ void outl(int port, unsigned int val) +{ + __asm__ __volatile__ ("outl %0, %w1\n\t" + : + : "a" (val), + "d" (port)); +} + +static __inline__ void insb(int port,void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\tinsb\n\t" + : "=D" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "memory", "cc"); +} + +static __inline__ void insw(int port,void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\tinsw\n\t" + : "=D" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "memory", "cc"); +} + +static __inline__ void insl(int port,void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\tinsl\n\t" + : "=D" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "memory", "cc"); +} + +static __inline__ void outsb(int port,const void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\toutsb\n\t" + : "=S" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "cc"); +} + +static __inline__ void outsw(int port,const void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\toutsw\n\t" + : "=S" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "cc"); +} + +static __inline__ void outsl(int port,const void *buf,int cnt) +{ + __asm__ __volatile__ ("cld\n\trepne\n\toutsl\n\t" + : "=S" (buf), "=c" (cnt) + : "d" (port), "0" (buf), "1" (cnt) : "cc"); +} diff --git a/sys/dev/x86/sercons.c b/sys/dev/x86/sercons.c new file mode 100644 index 0000000..e69de29 diff --git a/sys/dev/x86/sercons.h b/sys/dev/x86/sercons.h new file mode 100644 index 0000000..e69de29 diff --git a/sys/dev/x86/vgacons.c b/sys/dev/x86/vgacons.c new file mode 100644 index 0000000..4470824 --- /dev/null +++ b/sys/dev/x86/vgacons.c @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2006-2007 Ali Mashtizadeh + */ + +#include "ioport.h" +#include "vgacons.h" + +static short *VideoBuffer = (short *)0x000B8000; +static int CurrentX = 0; +static int CurrentY = 0; +static int SizeX = 80; +static int SizeY = 25; +static int Screen = 1; +static unsigned char TextAttribute = 0x70; /* Grey on Black */ + +#define VGA_BASE 0x370 + +#define VGA_ATC_INDEX 0x00 + VGA_BASE +#define VGA_ATC_DATA 0x01 + VGA_BASE +#define VGA_SEQ_INDEX 0x02 + VGA_BASE +#define VGA_SEQ_DATA 0x05 + VGA_BASE +#define VGA_PAL_RADDR 0x07 + VGA_BASE +#define VGA_PAL_WADDR 0x08 + VGA_BASE +#define VGA_PAL_DATA 0x09 + VGA_BASE +#define VGA_GDC_INDEX 0x0E + VGA_BASE +#define VGA_GDC_DATA 0x0F + VGA_BASE + +static uint8_t ModeBuffer[6]; + +void LockDisplay(void) +{ +} + +void UnlockDisplay(void) +{ +} + +void EnterFontMode(void) +{ + // Save VGA State + outb(VGA_SEQ_INDEX,0x02); + ModeBuffer[0] = inb(VGA_SEQ_DATA); + + outb(VGA_SEQ_INDEX,0x04); + ModeBuffer[1] = inb(VGA_SEQ_DATA); + + outb(VGA_GDC_INDEX,0x04); + ModeBuffer[2] = inb(VGA_GDC_DATA); + + outb(VGA_GDC_INDEX,0x05); + ModeBuffer[3] = inb(VGA_GDC_DATA); + + outb(VGA_GDC_INDEX,0x06); + ModeBuffer[4] = inb(VGA_GDC_DATA); + + outb(VGA_ATC_INDEX,0x10); + ModeBuffer[5] = inb(VGA_ATC_DATA); + + // Setup Font Mode +} + +void ExitFontMode(void) +{ + // Restore VGA State +} + + +void VGA_Init(void) +{ + int i = 0; + + for (i = 0;i < SizeX * SizeY;i++) + { + VideoBuffer[i] = (TextAttribute << 8) | ' '; + } + + CurrentX = 0; + CurrentY = 0; + + /* + * At initialization the video memory is located at 0xB8000. + * We will map the memory after memory management has been + * initialized. + */ +} + +void VGA_LateInit(void) +{ + // Map in video memory + // Set VideoBuffer pointer +} + +void VGA_ScrollDisplay(void) +{ + int i,j; + for (i = 1; i < SizeY; i++) + { + for (j = 0; j < SizeX; j++) + { + VideoBuffer[(i-1)*SizeX+j] = VideoBuffer[i*SizeX+j]; + } + } + for (j = 0; j < SizeX; j++) + VideoBuffer[(SizeY-1)*SizeX+j] = (TextAttribute << 8) | ' '; + return; +} + +void VGA_Putc(short c) +{ + c |= (TextAttribute << 8); + switch (c & 0xFF) + { + case '\n': + if (CurrentY >= (SizeY - 1)) { + VGA_ScrollDisplay(); + } else { + CurrentY++; + } + CurrentX = 0; + break; + case '\r': + break; + case '\t': + VGA_Putc(' '); + VGA_Putc(' '); + VGA_Putc(' '); + VGA_Putc(' '); + break; + default: + VideoBuffer[CurrentX + CurrentY * SizeX] = c; + CurrentX++; + if (CurrentX == SizeX) { + if (CurrentY >= (SizeY - 1)) { + VGA_ScrollDisplay(); + } else { + CurrentY++; + } + CurrentX = 0; + } + break; + } +} + +void VGA_Puts(const char *str) +{ + const char *p = str; + while (*p != '\0') + VGA_Putc(*p++); +} + +void Panic(const char *str) +{ + VGA_Puts(str); + while (1) + { + __asm__("hlt"); + } +} + diff --git a/sys/dev/x86/vgacons.h b/sys/dev/x86/vgacons.h new file mode 100644 index 0000000..792901d --- /dev/null +++ b/sys/dev/x86/vgacons.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2006-2008 Ali Mashtizadeh + */ + +#ifndef __VGA_H__ +#define __VGA_H__ + +/* + * Using 4 80x60 screens with an 8x8 font + */ +#define SCREEN_CONSOLE 1 +#define SCREEN_KLOG 2 +#define SCREEN_KDEBUG 3 +#define SCREEN_EXTRA 4 +#define MAX_SCREENS 4 + +#define COLOR_BLACK 0 +#define COLOR_BLUE 1 +#define COLOR_DARKGRAY 2 +#define COLOR_LIGHTBLUE 3 +#define COLOR_RED 4 +#define COLOR_MAGENTA 5 +#define COLOR_LIGHTRED 6 +#define COLOR_LIGHTMAGENTA 7 +#define COLOR_GREEN 8 +#define COLOR_CYAN 9 +#define COLOR_LIGHTGREEN 10 +#define COLOR_LIGHTCYAN 11 +#define COLOR_BROWN 12 +#define COLOR_LIGHTGREY 13 +#define COLOR_YELLOW 14 +#define COLOR_WHITE 15 + +void VGA_Init(void); +void VGA_LateInit(void); +void VGA_SwitchTo(int screen); +void VGA_LoadFont(void *fontBuffer, int maxLength); +void VGA_SaveFont(void *fontBuffer, int maxLength); +void VGA_ClearDisplay(void); +void VGA_ScollDisplay(void); +void VGA_Putc(short ch); +void VGA_Puts(const char *str); +void Panic(const char *str); + +#endif /* __VGA_H__ */ + diff --git a/sys/include/cdefs.h b/sys/include/cdefs.h new file mode 100644 index 0000000..00b57d8 --- /dev/null +++ b/sys/include/cdefs.h @@ -0,0 +1,13 @@ + +#ifndef __CDEFS_H__ +#define __CDEFS_H__ + +#include + +#define PACKED __attribute__((__packed__)) + +#define INLINE inline +#define NO_RETURN __attribute__((noreturn)) + +#endif /* __CDEFS_H__ */ + diff --git a/sys/include/kassert.h b/sys/include/kassert.h new file mode 100644 index 0000000..1e068aa --- /dev/null +++ b/sys/include/kassert.h @@ -0,0 +1,15 @@ + +#ifndef __KASSERT_H__ +#define __KASSERT_H__ + +#include + +#define ASSERT(x) if (!(x)) { Panic("ASSERT:"); } +#define PANIC Panic + +NO_RETURN void Panic(const char *str); + +int kprintf(const char *fmt, ...); + +#endif /* __KASSERT_H__ */ + diff --git a/sys/include/kconfig.h b/sys/include/kconfig.h new file mode 100644 index 0000000..6065340 --- /dev/null +++ b/sys/include/kconfig.h @@ -0,0 +1,11 @@ +/* + * Compile Time Kernel Configuration Options + */ + +#ifndef __KCONFIG_H__ +#define __KCONFIG_H__ + +#define MAX_CPUS 16 + +#endif /* __KCONFIG_H__ */ + diff --git a/sys/include/queue.h b/sys/include/queue.h new file mode 100644 index 0000000..6ce9f88 --- /dev/null +++ b/sys/include/queue.h @@ -0,0 +1,694 @@ +/*- + * Copyright (c) 1991, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)queue.h 8.5 (Berkeley) 8/20/94 + * $FreeBSD$ + */ + +#ifndef _SYS_QUEUE_H_ +#define _SYS_QUEUE_H_ + +#include + +/* + * This file defines four types of data structures: singly-linked lists, + * singly-linked tail queues, lists and tail queues. + * + * A singly-linked list is headed by a single forward pointer. The elements + * are singly linked for minimum space and pointer manipulation overhead at + * the expense of O(n) removal for arbitrary elements. New elements can be + * added to the list after an existing element or at the head of the list. + * Elements being removed from the head of the list should use the explicit + * macro for this purpose for optimum efficiency. A singly-linked list may + * only be traversed in the forward direction. Singly-linked lists are ideal + * for applications with large datasets and few or no removals or for + * implementing a LIFO queue. + * + * A singly-linked tail queue is headed by a pair of pointers, one to the + * head of the list and the other to the tail of the list. The elements are + * singly linked for minimum space and pointer manipulation overhead at the + * expense of O(n) removal for arbitrary elements. New elements can be added + * to the list after an existing element, at the head of the list, or at the + * end of the list. Elements being removed from the head of the tail queue + * should use the explicit macro for this purpose for optimum efficiency. + * A singly-linked tail queue may only be traversed in the forward direction. + * Singly-linked tail queues are ideal for applications with large datasets + * and few or no removals or for implementing a FIFO queue. + * + * A list is headed by a single forward pointer (or an array of forward + * pointers for a hash table header). The elements are doubly linked + * so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before + * or after an existing element or at the head of the list. A list + * may be traversed in either direction. + * + * A tail queue is headed by a pair of pointers, one to the head of the + * list and the other to the tail of the list. The elements are doubly + * linked so that an arbitrary element can be removed without a need to + * traverse the list. New elements can be added to the list before or + * after an existing element, at the head of the list, or at the end of + * the list. A tail queue may be traversed in either direction. + * + * For details on the use of these macros, see the queue(3) manual page. + * + * + * SLIST LIST STAILQ TAILQ + * _HEAD + + + + + * _HEAD_INITIALIZER + + + + + * _ENTRY + + + + + * _INIT + + + + + * _EMPTY + + + + + * _FIRST + + + + + * _NEXT + + + + + * _PREV - + - + + * _LAST - - + + + * _FOREACH + + + + + * _FOREACH_FROM + + + + + * _FOREACH_SAFE + + + + + * _FOREACH_FROM_SAFE + + + + + * _FOREACH_REVERSE - - - + + * _FOREACH_REVERSE_FROM - - - + + * _FOREACH_REVERSE_SAFE - - - + + * _FOREACH_REVERSE_FROM_SAFE - - - + + * _INSERT_HEAD + + + + + * _INSERT_BEFORE - + - + + * _INSERT_AFTER + + + + + * _INSERT_TAIL - - + + + * _CONCAT - - + + + * _REMOVE_AFTER + - + - + * _REMOVE_HEAD + - + - + * _REMOVE + + + + + * _SWAP + + + + + * + */ +#ifdef QUEUE_MACRO_DEBUG +/* Store the last 2 places the queue element or head was altered */ +struct qm_trace { + unsigned long lastline; + unsigned long prevline; + const char *lastfile; + const char *prevfile; +}; + +#define TRACEBUF struct qm_trace trace; +#define TRACEBUF_INITIALIZER { __FILE__, __LINE__, NULL, 0 } , +#define TRASHIT(x) do {(x) = (void *)-1;} while (0) +#define QMD_SAVELINK(name, link) void **name = (void *)&(link) + +#define QMD_TRACE_HEAD(head) do { \ + (head)->trace.prevline = (head)->trace.lastline; \ + (head)->trace.prevfile = (head)->trace.lastfile; \ + (head)->trace.lastline = __LINE__; \ + (head)->trace.lastfile = __FILE__; \ +} while (0) + +#define QMD_TRACE_ELEM(elem) do { \ + (elem)->trace.prevline = (elem)->trace.lastline; \ + (elem)->trace.prevfile = (elem)->trace.lastfile; \ + (elem)->trace.lastline = __LINE__; \ + (elem)->trace.lastfile = __FILE__; \ +} while (0) + +#else +#define QMD_TRACE_ELEM(elem) +#define QMD_TRACE_HEAD(head) +#define QMD_SAVELINK(name, link) +#define TRACEBUF +#define TRACEBUF_INITIALIZER +#define TRASHIT(x) +#endif /* QUEUE_MACRO_DEBUG */ + +/* + * Singly-linked List declarations. + */ +#define SLIST_HEAD(name, type) \ +struct name { \ + struct type *slh_first; /* first element */ \ +} + +#define SLIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define SLIST_ENTRY(type) \ +struct { \ + struct type *sle_next; /* next element */ \ +} + +/* + * Singly-linked List functions. + */ +#define SLIST_EMPTY(head) ((head)->slh_first == NULL) + +#define SLIST_FIRST(head) ((head)->slh_first) + +#define SLIST_FOREACH(var, head, field) \ + for ((var) = SLIST_FIRST((head)); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ + (var); \ + (var) = SLIST_NEXT((var), field)) + +#define SLIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = SLIST_FIRST((head)); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : SLIST_FIRST((head))); \ + (var) && ((tvar) = SLIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define SLIST_FOREACH_PREVPTR(var, varp, head, field) \ + for ((varp) = &SLIST_FIRST((head)); \ + ((var) = *(varp)) != NULL; \ + (varp) = &SLIST_NEXT((var), field)) + +#define SLIST_INIT(head) do { \ + SLIST_FIRST((head)) = NULL; \ +} while (0) + +#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \ + SLIST_NEXT((slistelm), field) = (elm); \ +} while (0) + +#define SLIST_INSERT_HEAD(head, elm, field) do { \ + SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \ + SLIST_FIRST((head)) = (elm); \ +} while (0) + +#define SLIST_NEXT(elm, field) ((elm)->field.sle_next) + +#define SLIST_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.sle_next); \ + if (SLIST_FIRST((head)) == (elm)) { \ + SLIST_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = SLIST_FIRST((head)); \ + while (SLIST_NEXT(curelm, field) != (elm)) \ + curelm = SLIST_NEXT(curelm, field); \ + SLIST_REMOVE_AFTER(curelm, field); \ + } \ + TRASHIT(*oldnext); \ +} while (0) + +#define SLIST_REMOVE_AFTER(elm, field) do { \ + SLIST_NEXT(elm, field) = \ + SLIST_NEXT(SLIST_NEXT(elm, field), field); \ +} while (0) + +#define SLIST_REMOVE_HEAD(head, field) do { \ + SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \ +} while (0) + +#define SLIST_SWAP(head1, head2, type) do { \ + struct type *swap_first = SLIST_FIRST(head1); \ + SLIST_FIRST(head1) = SLIST_FIRST(head2); \ + SLIST_FIRST(head2) = swap_first; \ +} while (0) + +/* + * Singly-linked Tail queue declarations. + */ +#define STAILQ_HEAD(name, type) \ +struct name { \ + struct type *stqh_first;/* first element */ \ + struct type **stqh_last;/* addr of last next element */ \ +} + +#define STAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).stqh_first } + +#define STAILQ_ENTRY(type) \ +struct { \ + struct type *stqe_next; /* next element */ \ +} + +/* + * Singly-linked Tail queue functions. + */ +#define STAILQ_CONCAT(head1, head2) do { \ + if (!STAILQ_EMPTY((head2))) { \ + *(head1)->stqh_last = (head2)->stqh_first; \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_INIT((head2)); \ + } \ +} while (0) + +#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL) + +#define STAILQ_FIRST(head) ((head)->stqh_first) + +#define STAILQ_FOREACH(var, head, field) \ + for((var) = STAILQ_FIRST((head)); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ + (var); \ + (var) = STAILQ_NEXT((var), field)) + +#define STAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = STAILQ_FIRST((head)); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : STAILQ_FIRST((head))); \ + (var) && ((tvar) = STAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define STAILQ_INIT(head) do { \ + STAILQ_FIRST((head)) = NULL; \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_NEXT((tqelm), field) = (elm); \ +} while (0) + +#define STAILQ_INSERT_HEAD(head, elm, field) do { \ + if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ + STAILQ_FIRST((head)) = (elm); \ +} while (0) + +#define STAILQ_INSERT_TAIL(head, elm, field) do { \ + STAILQ_NEXT((elm), field) = NULL; \ + *(head)->stqh_last = (elm); \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_LAST(head, type, field) \ + (STAILQ_EMPTY((head)) ? NULL : \ + __containerof((head)->stqh_last, struct type, field.stqe_next)) + +#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next) + +#define STAILQ_REMOVE(head, elm, type, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.stqe_next); \ + if (STAILQ_FIRST((head)) == (elm)) { \ + STAILQ_REMOVE_HEAD((head), field); \ + } \ + else { \ + struct type *curelm = STAILQ_FIRST((head)); \ + while (STAILQ_NEXT(curelm, field) != (elm)) \ + curelm = STAILQ_NEXT(curelm, field); \ + STAILQ_REMOVE_AFTER(head, curelm, field); \ + } \ + TRASHIT(*oldnext); \ +} while (0) + +#define STAILQ_REMOVE_AFTER(head, elm, field) do { \ + if ((STAILQ_NEXT(elm, field) = \ + STAILQ_NEXT(STAILQ_NEXT(elm, field), field)) == NULL) \ + (head)->stqh_last = &STAILQ_NEXT((elm), field); \ +} while (0) + +#define STAILQ_REMOVE_HEAD(head, field) do { \ + if ((STAILQ_FIRST((head)) = \ + STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \ + (head)->stqh_last = &STAILQ_FIRST((head)); \ +} while (0) + +#define STAILQ_SWAP(head1, head2, type) do { \ + struct type *swap_first = STAILQ_FIRST(head1); \ + struct type **swap_last = (head1)->stqh_last; \ + STAILQ_FIRST(head1) = STAILQ_FIRST(head2); \ + (head1)->stqh_last = (head2)->stqh_last; \ + STAILQ_FIRST(head2) = swap_first; \ + (head2)->stqh_last = swap_last; \ + if (STAILQ_EMPTY(head1)) \ + (head1)->stqh_last = &STAILQ_FIRST(head1); \ + if (STAILQ_EMPTY(head2)) \ + (head2)->stqh_last = &STAILQ_FIRST(head2); \ +} while (0) + + +/* + * List declarations. + */ +#define LIST_HEAD(name, type) \ +struct name { \ + struct type *lh_first; /* first element */ \ +} + +#define LIST_HEAD_INITIALIZER(head) \ + { NULL } + +#define LIST_ENTRY(type) \ +struct { \ + struct type *le_next; /* next element */ \ + struct type **le_prev; /* address of previous next element */ \ +} + +/* + * List functions. + */ + +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_LIST_CHECK_HEAD(head, field) do { \ + if (LIST_FIRST((head)) != NULL && \ + LIST_FIRST((head))->field.le_prev != \ + &LIST_FIRST((head))) \ + panic("Bad list head %p first->prev != head", (head)); \ +} while (0) + +#define QMD_LIST_CHECK_NEXT(elm, field) do { \ + if (LIST_NEXT((elm), field) != NULL && \ + LIST_NEXT((elm), field)->field.le_prev != \ + &((elm)->field.le_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +#define QMD_LIST_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.le_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_LIST_CHECK_HEAD(head, field) +#define QMD_LIST_CHECK_NEXT(elm, field) +#define QMD_LIST_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define LIST_EMPTY(head) ((head)->lh_first == NULL) + +#define LIST_FIRST(head) ((head)->lh_first) + +#define LIST_FOREACH(var, head, field) \ + for ((var) = LIST_FIRST((head)); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ + (var); \ + (var) = LIST_NEXT((var), field)) + +#define LIST_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = LIST_FIRST((head)); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : LIST_FIRST((head))); \ + (var) && ((tvar) = LIST_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define LIST_INIT(head) do { \ + LIST_FIRST((head)) = NULL; \ +} while (0) + +#define LIST_INSERT_AFTER(listelm, elm, field) do { \ + QMD_LIST_CHECK_NEXT(listelm, field); \ + if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\ + LIST_NEXT((listelm), field)->field.le_prev = \ + &LIST_NEXT((elm), field); \ + LIST_NEXT((listelm), field) = (elm); \ + (elm)->field.le_prev = &LIST_NEXT((listelm), field); \ +} while (0) + +#define LIST_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_LIST_CHECK_PREV(listelm, field); \ + (elm)->field.le_prev = (listelm)->field.le_prev; \ + LIST_NEXT((elm), field) = (listelm); \ + *(listelm)->field.le_prev = (elm); \ + (listelm)->field.le_prev = &LIST_NEXT((elm), field); \ +} while (0) + +#define LIST_INSERT_HEAD(head, elm, field) do { \ + QMD_LIST_CHECK_HEAD((head), field); \ + if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \ + LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\ + LIST_FIRST((head)) = (elm); \ + (elm)->field.le_prev = &LIST_FIRST((head)); \ +} while (0) + +#define LIST_NEXT(elm, field) ((elm)->field.le_next) + +#define LIST_PREV(elm, head, type, field) \ + ((elm)->field.le_prev == &LIST_FIRST((head)) ? NULL : \ + __containerof((elm)->field.le_prev, struct type, field.le_next)) + +#define LIST_REMOVE(elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.le_next); \ + QMD_SAVELINK(oldprev, (elm)->field.le_prev); \ + QMD_LIST_CHECK_NEXT(elm, field); \ + QMD_LIST_CHECK_PREV(elm, field); \ + if (LIST_NEXT((elm), field) != NULL) \ + LIST_NEXT((elm), field)->field.le_prev = \ + (elm)->field.le_prev; \ + *(elm)->field.le_prev = LIST_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ +} while (0) + +#define LIST_SWAP(head1, head2, type, field) do { \ + struct type *swap_tmp = LIST_FIRST((head1)); \ + LIST_FIRST((head1)) = LIST_FIRST((head2)); \ + LIST_FIRST((head2)) = swap_tmp; \ + if ((swap_tmp = LIST_FIRST((head1))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head1)); \ + if ((swap_tmp = LIST_FIRST((head2))) != NULL) \ + swap_tmp->field.le_prev = &LIST_FIRST((head2)); \ +} while (0) + +/* + * Tail queue declarations. + */ +#define TAILQ_HEAD(name, type) \ +struct name { \ + struct type *tqh_first; /* first element */ \ + struct type **tqh_last; /* addr of last next element */ \ + TRACEBUF \ +} + +#define TAILQ_HEAD_INITIALIZER(head) \ + { NULL, &(head).tqh_first, TRACEBUF_INITIALIZER } + +#define TAILQ_ENTRY(type) \ +struct { \ + struct type *tqe_next; /* next element */ \ + struct type **tqe_prev; /* address of previous next element */ \ + TRACEBUF \ +} + +/* + * Tail queue functions. + */ +#if (defined(_KERNEL) && defined(INVARIANTS)) +#define QMD_TAILQ_CHECK_HEAD(head, field) do { \ + if (!TAILQ_EMPTY(head) && \ + TAILQ_FIRST((head))->field.tqe_prev != \ + &TAILQ_FIRST((head))) \ + panic("Bad tailq head %p first->prev != head", (head)); \ +} while (0) + +#define QMD_TAILQ_CHECK_TAIL(head, field) do { \ + if (*(head)->tqh_last != NULL) \ + panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head)); \ +} while (0) + +#define QMD_TAILQ_CHECK_NEXT(elm, field) do { \ + if (TAILQ_NEXT((elm), field) != NULL && \ + TAILQ_NEXT((elm), field)->field.tqe_prev != \ + &((elm)->field.tqe_next)) \ + panic("Bad link elm %p next->prev != elm", (elm)); \ +} while (0) + +#define QMD_TAILQ_CHECK_PREV(elm, field) do { \ + if (*(elm)->field.tqe_prev != (elm)) \ + panic("Bad link elm %p prev->next != elm", (elm)); \ +} while (0) +#else +#define QMD_TAILQ_CHECK_HEAD(head, field) +#define QMD_TAILQ_CHECK_TAIL(head, headname) +#define QMD_TAILQ_CHECK_NEXT(elm, field) +#define QMD_TAILQ_CHECK_PREV(elm, field) +#endif /* (_KERNEL && INVARIANTS) */ + +#define TAILQ_CONCAT(head1, head2, field) do { \ + if (!TAILQ_EMPTY(head2)) { \ + *(head1)->tqh_last = (head2)->tqh_first; \ + (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \ + (head1)->tqh_last = (head2)->tqh_last; \ + TAILQ_INIT((head2)); \ + QMD_TRACE_HEAD(head1); \ + QMD_TRACE_HEAD(head2); \ + } \ +} while (0) + +#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL) + +#define TAILQ_FIRST(head) ((head)->tqh_first) + +#define TAILQ_FOREACH(var, head, field) \ + for ((var) = TAILQ_FIRST((head)); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_FROM(var, head, field) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var); \ + (var) = TAILQ_NEXT((var), field)) + +#define TAILQ_FOREACH_SAFE(var, head, field, tvar) \ + for ((var) = TAILQ_FIRST((head)); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_FROM_SAFE(var, head, field, tvar) \ + for ((var) = ((var) ? (var) : TAILQ_FIRST((head))); \ + (var) && ((tvar) = TAILQ_NEXT((var), field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_FROM(var, head, headname, field) \ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var); \ + (var) = TAILQ_PREV((var), headname, field)) + +#define TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \ + for ((var) = TAILQ_LAST((head), headname); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_FOREACH_REVERSE_FROM_SAFE(var, head, headname, field, tvar) \ + for ((var) = ((var) ? (var) : TAILQ_LAST((head), headname)); \ + (var) && ((tvar) = TAILQ_PREV((var), headname, field), 1); \ + (var) = (tvar)) + +#define TAILQ_INIT(head) do { \ + TAILQ_FIRST((head)) = NULL; \ + (head)->tqh_last = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ +} while (0) + +#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \ + QMD_TAILQ_CHECK_NEXT(listelm, field); \ + if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else { \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + } \ + TAILQ_NEXT((listelm), field) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \ + QMD_TAILQ_CHECK_PREV(listelm, field); \ + (elm)->field.tqe_prev = (listelm)->field.tqe_prev; \ + TAILQ_NEXT((elm), field) = (listelm); \ + *(listelm)->field.tqe_prev = (elm); \ + (listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_ELEM(&(elm)->field); \ + QMD_TRACE_ELEM(&listelm->field); \ +} while (0) + +#define TAILQ_INSERT_HEAD(head, elm, field) do { \ + QMD_TAILQ_CHECK_HEAD(head, field); \ + if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \ + TAILQ_FIRST((head))->field.tqe_prev = \ + &TAILQ_NEXT((elm), field); \ + else \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + TAILQ_FIRST((head)) = (elm); \ + (elm)->field.tqe_prev = &TAILQ_FIRST((head)); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_INSERT_TAIL(head, elm, field) do { \ + QMD_TAILQ_CHECK_TAIL(head, field); \ + TAILQ_NEXT((elm), field) = NULL; \ + (elm)->field.tqe_prev = (head)->tqh_last; \ + *(head)->tqh_last = (elm); \ + (head)->tqh_last = &TAILQ_NEXT((elm), field); \ + QMD_TRACE_HEAD(head); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_LAST(head, headname) \ + (*(((struct headname *)((head)->tqh_last))->tqh_last)) + +#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next) + +#define TAILQ_PREV(elm, headname, field) \ + (*(((struct headname *)((elm)->field.tqe_prev))->tqh_last)) + +#define TAILQ_REMOVE(head, elm, field) do { \ + QMD_SAVELINK(oldnext, (elm)->field.tqe_next); \ + QMD_SAVELINK(oldprev, (elm)->field.tqe_prev); \ + QMD_TAILQ_CHECK_NEXT(elm, field); \ + QMD_TAILQ_CHECK_PREV(elm, field); \ + if ((TAILQ_NEXT((elm), field)) != NULL) \ + TAILQ_NEXT((elm), field)->field.tqe_prev = \ + (elm)->field.tqe_prev; \ + else { \ + (head)->tqh_last = (elm)->field.tqe_prev; \ + QMD_TRACE_HEAD(head); \ + } \ + *(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \ + TRASHIT(*oldnext); \ + TRASHIT(*oldprev); \ + QMD_TRACE_ELEM(&(elm)->field); \ +} while (0) + +#define TAILQ_SWAP(head1, head2, type, field) do { \ + struct type *swap_first = (head1)->tqh_first; \ + struct type **swap_last = (head1)->tqh_last; \ + (head1)->tqh_first = (head2)->tqh_first; \ + (head1)->tqh_last = (head2)->tqh_last; \ + (head2)->tqh_first = swap_first; \ + (head2)->tqh_last = swap_last; \ + if ((swap_first = (head1)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head1)->tqh_first; \ + else \ + (head1)->tqh_last = &(head1)->tqh_first; \ + if ((swap_first = (head2)->tqh_first) != NULL) \ + swap_first->field.tqe_prev = &(head2)->tqh_first; \ + else \ + (head2)->tqh_last = &(head2)->tqh_first; \ +} while (0) + +#endif /* !_SYS_QUEUE_H_ */ diff --git a/sys/kern/libc.c b/sys/kern/libc.c new file mode 100644 index 0000000..e16bdff --- /dev/null +++ b/sys/kern/libc.c @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * Copyright (c) 2006-2008 Ali Mashtizadeh + * All rights reserved. + */ + +#include + +char * +strcpy(char *to, const char *from) +{ + char *save = to; + + for (; (*to = *from); ++from, ++to); + + return save; +} + +int +strcmp(const char *s1, const char *s2) +{ + while (*s1 == *s2++) + if (*s1++ == 0) + return 0; + + return (*(const uint8_t *)s1 - *(const uint8_t *)(s2 - 1)); +} + +size_t +strlen(const char *str) +{ + const char *s; + + for (s = str; *s; ++s); + + return (s - str); +} + +void * +memset(void *dst, uint8_t c, size_t length) +{ + uint8_t *p = (uint8_t *)dst; + + do { + *p = c; + p += 1; + } while (--length != 0); + + return dst; +} + diff --git a/sys/kern/malloc.c b/sys/kern/malloc.c new file mode 100644 index 0000000..a7d4e0c --- /dev/null +++ b/sys/kern/malloc.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#include +#include + +#include + +void palloc_init() +{ +} + +void palloc_add_region(uintptr_t start, uintptr_t len) +{ +} + +void *palloc_alloc(uintptr_t len) +{ +} + +void palloc_free(void *region) +{ +} + +void *palloc_alloc_lpage() +{ +} + +void palloc_free_lpage(void *lpg) +{ +} + +void *palloc_alloc_page() +{ +} + +void palloc_free_page(void *pg) +{ +} + diff --git a/sys/kern/palloc.c b/sys/kern/palloc.c new file mode 100644 index 0000000..deec004 --- /dev/null +++ b/sys/kern/palloc.c @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#include +#include + +#include +#include +#include + +#include "../amd64/amd64.h" + +typedef struct FreePage +{ + LIST_ENTRY(FreePage) entries; +} FreePage; + +LIST_HEAD(FreeListHead, FreePage) freeList; + +void PAlloc_Init() +{ + LIST_INIT(&freeList); +} + +void PAlloc_AddRegion(uintptr_t start, uintptr_t len) +{ + uintptr_t i; + FreePage *pg; + + kprintf("PAlloc_AddRegion(%08llx, %08llx)\n", start, len); + + if ((start % PGSIZE) != 0) + Panic("Region start is not page aligned!"); + if ((len % PGSIZE) != 0) + Panic("Region length is not page aligned!"); + + for (i = 0; i < len; i += PGSIZE) + { + pg = (void *)(start + i); + LIST_INSERT_HEAD(&freeList, pg, entries); + } +} + +void *PAlloc_AllocPage() +{ +} + +void PAlloc_FreePage(void *region) +{ +} + diff --git a/sys/kern/printf.c b/sys/kern/printf.c new file mode 100644 index 0000000..c0b672e --- /dev/null +++ b/sys/kern/printf.c @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * Copyright (c) 2006-2008 Ali Mashtizadeh + * All rights reserved. + */ + +#include +#include + +#include + +#include "../dev/console.h" + +// static unsigned long getuint(va_list *ap, int lflag) +#define getuint(ap, lflag) \ + (lflag == 8) ? va_arg(ap, uint64_t) : \ + (lflag == 4) ? va_arg(ap, uint32_t) : \ + (lflag == 2) ? va_arg(ap, uint32_t) : \ + (lflag == 1) ? va_arg(ap, uint32_t) : 0 + +// static long getint(va_list *ap, int lflag) +#define getint(ap, lflag) \ + (lflag == 8) ? va_arg(ap, int64_t) : \ + (lflag == 4) ? va_arg(ap, int32_t) : \ + (lflag == 2) ? va_arg(ap, int32_t) : \ + (lflag == 1) ? va_arg(ap, int32_t) : 0 + +static const char *numberstring_lower = "0123456789abcdef"; +static const char *numberstring_upper = "0123456789ABCDEF"; + +static void printnum(void (*func)(int, void*),void *handle, + uint64_t num,int base,int width,int padc) +{ + char buf[64]; + char *p = buf; + int spaces; + if (base < 0) + { + base = -base; + do { + *p = numberstring_upper[num % base]; + p++; + } while (num /= base); + } else { + do { + *p = numberstring_lower[num % base]; + p++; + } while (num /= base); + } + + // Print Spacers + spaces = width - (p - buf); + while (spaces > 0) + { + func(padc, handle); + spaces--; + } + + // Print Number + while (p != buf) { + p--; + func((int)*p, handle); + } +} + +int kvprintf(char const *fmt, void (*func)(int,void *), void *handle, va_list ap) +{ + const char *p; + int ch; + uint64_t unum; + int64_t num; + int lflag, width, padc, precision, altflag; + + while (1) { + while ((ch = *(unsigned char *)fmt++) != '%') { + if (ch == '\0') return -1; + func(ch, handle); + } + + width = -1; + lflag = 4; + altflag = 0; + padc = ' '; +again: + switch (ch = *(unsigned char *)fmt++) { + case '-': + padc = '-'; + goto again; + case '0': + padc = '0'; + goto again; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + width = 0; + while (1) { + width = 10 * width + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + { + break; + } + fmt++; + if (ch == '\0') + { + fmt--; + goto again; + } + } + goto again; + case 'c': + func(va_arg(ap, int) & 0xff, handle); + break; + case 's': + p = va_arg(ap, char *); + ASSERT(p != 0); + while (*p != '\0') + { + func(*p++, handle); + } + break; + case 'd': + num = getint(ap, lflag); + if (num < 0) { + func('-', handle); + unum = -num; + } else { + unum = num; + } + printnum(func, handle, unum, 10, width, padc); + break; + case 'u': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 10, width, padc); + break; + case 'o': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 8, width, padc); + break; + case 'p': + unum = (unsigned long)va_arg(ap, void *); + printnum(func, handle, unum, 8, width, padc); + break; + case 'x': + unum = getuint(ap, lflag); + printnum(func, handle, unum, 16, width, padc); + break; + case 'X': + unum = getuint(ap, lflag); + printnum(func, handle, unum, -16, width, padc); + break; + case 'l': + lflag = 8; + goto again; + case '%': + default: // Print Literally + func(ch, handle); + break; + } + } + return 0; +} + +void consoleputc(int c,void* handle) +{ + Console_Putc(c); +} + +int kprintf(const char *fmt, ...) +{ + int ret; + va_list ap; + + va_start(ap, fmt); + ret = kvprintf(fmt, consoleputc, 0, ap); + va_end(ap); + + return ret; +} + diff --git a/sys/kern/salloc.c b/sys/kern/salloc.c new file mode 100644 index 0000000..69429b0 --- /dev/null +++ b/sys/kern/salloc.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#include +#include + +#include + +Slab * +salloc_new(uintptr_t objsz) +{ +} + +void +salloc_destroy(Slab *) +{ +} + +void * +salloc_alloc(Slab *slab) +{ +} + +void +salloc_free(Slab *slab, void *region) +{ +} + diff --git a/sys/kern/string.c b/sys/kern/string.c new file mode 100644 index 0000000..5fa261b --- /dev/null +++ b/sys/kern/string.c @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2014 Stanford University + * All rights reserved. + */ + +#include + +String * +String_Alloc(uintptr_t rsvd) +{ +} + +void +String_Free(String *str) +{ +} + +size_t +String_Length(String *str) +{ +} + +String * +String_Copy(String *str) +{ +} + +void +String_Append(String *dst, String *src) +{ +} + +int +String_Compare(String *s1, String *s2) +{ +} + +void +String_Append(String *, String *src) +{ +} +