Initial commit
This commit is contained in:
commit
11c151b60e
135
SConstruct
Normal file
135
SConstruct
Normal file
@ -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')
|
||||||
|
|
24
include/stdarg.h
Normal file
24
include/stdarg.h
Normal file
@ -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_ */
|
10
include/stddef.h
Normal file
10
include/stddef.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef __STDDEF_H__
|
||||||
|
#define __STDDEF_H__
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STDDEF_H__ */
|
||||||
|
|
22
include/stdint.h
Normal file
22
include/stdint.h
Normal file
@ -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_ */
|
||||||
|
|
10
include/stdlib.h
Normal file
10
include/stdlib.h
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
#ifndef __STDLIB_H__
|
||||||
|
#define __STDLIB_H__
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL ((void *)0)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* __STDLIB_H__ */
|
||||||
|
|
BIN
pxelinux/castor
Executable file
BIN
pxelinux/castor
Executable file
Binary file not shown.
554
pxelinux/castor.log
Normal file
554
pxelinux/castor.log
Normal file
@ -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
|
BIN
pxelinux/ldlinux.c32
Normal file
BIN
pxelinux/ldlinux.c32
Normal file
Binary file not shown.
BIN
pxelinux/libcom32.c32
Normal file
BIN
pxelinux/libcom32.c32
Normal file
Binary file not shown.
BIN
pxelinux/libutil.c32
Normal file
BIN
pxelinux/libutil.c32
Normal file
Binary file not shown.
BIN
pxelinux/mboot.c32
Normal file
BIN
pxelinux/mboot.c32
Normal file
Binary file not shown.
BIN
pxelinux/menu.c32
Normal file
BIN
pxelinux/menu.c32
Normal file
Binary file not shown.
BIN
pxelinux/pxelinux.0
Normal file
BIN
pxelinux/pxelinux.0
Normal file
Binary file not shown.
15
pxelinux/pxelinux.cfg/default
Normal file
15
pxelinux/pxelinux.cfg/default
Normal file
@ -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
|
||||||
|
|
4
pxelinux/run-castor
Executable file
4
pxelinux/run-castor
Executable file
@ -0,0 +1,4 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
qemu-system-x86_64 -bootp tftp://10.0.2.2/pxelinux.0 -tftp ./
|
||||||
|
|
4
pxelinux/run-castor-dbg
Executable file
4
pxelinux/run-castor-dbg
Executable file
@ -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 ./
|
||||||
|
|
BIN
pxelinux/vesamenu.c32
Normal file
BIN
pxelinux/vesamenu.c32
Normal file
Binary file not shown.
39
sys/SConscript
Normal file
39
sys/SConscript
Normal file
@ -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)
|
||||||
|
|
183
sys/amd64/amd64.h
Normal file
183
sys/amd64/amd64.h
Normal file
@ -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__ */
|
||||||
|
|
329
sys/amd64/amd64op.h
Normal file
329
sys/amd64/amd64op.h
Normal file
@ -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__ */
|
||||||
|
|
10
sys/amd64/asm.h
Normal file
10
sys/amd64/asm.h
Normal file
@ -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
|
||||||
|
|
76
sys/amd64/ioapic.c
Normal file
76
sys/amd64/ioapic.c
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* IOAPIC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
|
123
sys/amd64/lapic.c
Normal file
123
sys/amd64/lapic.c
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
/*
|
||||||
|
* LAPIC
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
86
sys/amd64/machine.c
Normal file
86
sys/amd64/machine.c
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kconfig.h>
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
#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();
|
||||||
|
}
|
||||||
|
|
214
sys/amd64/mbentry.c
Normal file
214
sys/amd64/mbentry.c
Normal file
@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Multiboot C Entry
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kassert.h>
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
|
#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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
117
sys/amd64/multiboot.S
Normal file
117
sys/amd64/multiboot.S
Normal file
@ -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
|
||||||
|
|
265
sys/amd64/multiboot.h
Normal file
265
sys/amd64/multiboot.h
Normal file
@ -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 */
|
127
sys/amd64/trap.c
Normal file
127
sys/amd64/trap.c
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kconfig.h>
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
#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) { }
|
||||||
|
}
|
||||||
|
|
74
sys/amd64/trap.h
Normal file
74
sys/amd64/trap.h
Normal file
@ -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__ */
|
||||||
|
|
196
sys/amd64/trapentry.S
Normal file
196
sys/amd64/trapentry.S
Normal file
@ -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
|
||||||
|
|
14
sys/dev/console.h
Normal file
14
sys/dev/console.h
Normal file
@ -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__ */
|
||||||
|
|
101
sys/dev/x86/ioport.h
Normal file
101
sys/dev/x86/ioport.h
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* HyperKernel - kernel/arch/x86/cpufunc.h
|
||||||
|
* Copyright (c) 2006-2007 Mashtizadeh Corporation
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
0
sys/dev/x86/sercons.c
Normal file
0
sys/dev/x86/sercons.c
Normal file
0
sys/dev/x86/sercons.h
Normal file
0
sys/dev/x86/sercons.h
Normal file
159
sys/dev/x86/vgacons.c
Normal file
159
sys/dev/x86/vgacons.c
Normal file
@ -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");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
46
sys/dev/x86/vgacons.h
Normal file
46
sys/dev/x86/vgacons.h
Normal file
@ -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__ */
|
||||||
|
|
13
sys/include/cdefs.h
Normal file
13
sys/include/cdefs.h
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
|
||||||
|
#ifndef __CDEFS_H__
|
||||||
|
#define __CDEFS_H__
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#define PACKED __attribute__((__packed__))
|
||||||
|
|
||||||
|
#define INLINE inline
|
||||||
|
#define NO_RETURN __attribute__((noreturn))
|
||||||
|
|
||||||
|
#endif /* __CDEFS_H__ */
|
||||||
|
|
15
sys/include/kassert.h
Normal file
15
sys/include/kassert.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
|
||||||
|
#ifndef __KASSERT_H__
|
||||||
|
#define __KASSERT_H__
|
||||||
|
|
||||||
|
#include <cdefs.h>
|
||||||
|
|
||||||
|
#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__ */
|
||||||
|
|
11
sys/include/kconfig.h
Normal file
11
sys/include/kconfig.h
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
/*
|
||||||
|
* Compile Time Kernel Configuration Options
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __KCONFIG_H__
|
||||||
|
#define __KCONFIG_H__
|
||||||
|
|
||||||
|
#define MAX_CPUS 16
|
||||||
|
|
||||||
|
#endif /* __KCONFIG_H__ */
|
||||||
|
|
694
sys/include/queue.h
Normal file
694
sys/include/queue.h
Normal file
@ -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 <cdefs.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 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_ */
|
51
sys/kern/libc.c
Normal file
51
sys/kern/libc.c
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* Copyright (c) 2006-2008 Ali Mashtizadeh
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
42
sys/kern/malloc.c
Normal file
42
sys/kern/malloc.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
53
sys/kern/palloc.c
Normal file
53
sys/kern/palloc.c
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <cdefs.h>
|
||||||
|
#include <kassert.h>
|
||||||
|
#include <queue.h>
|
||||||
|
|
||||||
|
#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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
186
sys/kern/printf.c
Normal file
186
sys/kern/printf.c
Normal file
@ -0,0 +1,186 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* Copyright (c) 2006-2008 Ali Mashtizadeh
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
||||||
|
|
30
sys/kern/salloc.c
Normal file
30
sys/kern/salloc.c
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
#include <kassert.h>
|
||||||
|
|
||||||
|
Slab *
|
||||||
|
salloc_new(uintptr_t objsz)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
salloc_destroy(Slab *)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
salloc_alloc(Slab *slab)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
salloc_free(Slab *slab, void *region)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
42
sys/kern/string.c
Normal file
42
sys/kern/string.c
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2013-2014 Stanford University
|
||||||
|
* All rights reserved.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user