/branches/dd/tools/mkhord.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/tools/xtui.py |
---|
File deleted |
/branches/dd/tools/xstruct.py |
---|
File deleted |
/branches/dd/tools/mkfat.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/tools/mktmpfs.py |
---|
32,107 → 32,69 |
import sys |
import os |
import xstruct |
import struct |
exclude_names = set(['.svn']) |
def align_up(size, alignment): |
return (((size) + ((alignment) - 1)) & ~((alignment) - 1)) |
HEADER = """little: |
char tag[5] /* 'TMPFS' */ |
""" |
DENTRY_NONE = """little: |
uint8_t kind /* NONE */ |
uint32_t fname_len /* 0 */ |
""" |
DENTRY_FILE = """little: |
uint8_t kind /* FILE */ |
uint32_t fname_len /* filename length */ |
char fname[%d] /* filename */ |
uint32_t flen /* file length */ |
""" |
DENTRY_DIRECTORY = """little: |
uint8_t kind /* DIRECTORY */ |
uint32_t fname_len /* filename length */ |
char fname[%d] /* filename */ |
""" |
TMPFS_NONE = 0 |
TMPFS_FILE = 1 |
TMPFS_DIRECTORY = 2 |
def usage(prname): |
"Print usage syntax" |
print prname + " <PATH> <IMAGE>" |
print prname + " <ALIGNMENT> <PATH> <IMAGE>" |
def recursion(root, outf): |
"Recursive directory walk" |
def main(): |
if (len(sys.argv) < 4): |
usage(sys.argv[0]) |
return |
for name in os.listdir(root): |
canon = os.path.join(root, name) |
if (os.path.isfile(canon) and (not name in exclude_names)): |
size = os.path.getsize(canon) |
if (not sys.argv[1].isdigit()): |
print "<ALIGNMENT> must be a number" |
return |
align = int(sys.argv[1], 0) |
path = os.path.abspath(sys.argv[2]) |
if (not os.path.isdir(path)): |
print "<PATH> must be a directory" |
return |
header_size = align_up(18, align) |
payload_size = 0 |
outf = file(sys.argv[3], "w") |
outf.write(struct.pack("<" + ("%d" % header_size) + "x")) |
for root, dirs, files in os.walk(path): |
relpath = root[len(path):len(root)] |
for name in files: |
canon = os.path.join(relpath, name) |
outf.write(struct.pack("<BL" + ("%d" % len(canon)) + "s", 1, len(canon), canon)) |
payload_size += 5 + len(canon) |
dentry = xstruct.create(DENTRY_FILE % len(name)) |
dentry.kind = TMPFS_FILE |
dentry.fname_len = len(name) |
dentry.fname = name |
dentry.flen = size |
fn = os.path.join(root, name) |
size = os.path.getsize(fn) |
rd = 0; |
outf.write(struct.pack("<L", size)) |
payload_size += 4 |
outf.write(dentry.pack()) |
inf = file(canon, "r") |
rd = 0; |
inf = file(fn, "r") |
while (rd < size): |
data = inf.read(4096); |
outf.write(data) |
payload_size += len(data) |
rd += len(data) |
inf.close() |
if (os.path.isdir(canon) and (not name in exclude_names)): |
dentry = xstruct.create(DENTRY_DIRECTORY % len(name)) |
dentry.kind = TMPFS_DIRECTORY |
dentry.fname_len = len(name) |
dentry.fname = name |
outf.write(dentry.pack()) |
recursion(canon, outf) |
dentry = xstruct.create(DENTRY_NONE) |
dentry.kind = TMPFS_NONE |
dentry.fname_len = 0 |
outf.write(dentry.pack()) |
def main(): |
if (len(sys.argv) < 3): |
usage(sys.argv[0]) |
return |
for name in dirs: |
canon = os.path.join(relpath, name) |
outf.write(struct.pack("<BL" + ("%d" % len(canon)) + "s", 2, len(canon), canon)) |
payload_size += 5 + len(canon) |
path = os.path.abspath(sys.argv[1]) |
if (not os.path.isdir(path)): |
print "<PATH> must be a directory" |
return |
aligned_size = align_up(payload_size, align) |
outf = file(sys.argv[2], "w") |
if (aligned_size - payload_size > 0): |
outf.write(struct.pack("<" + ("%d" % (aligned_size - payload_size)) + "x")) |
header = xstruct.create(HEADER) |
header.tag = "TMPFS" |
outf.write(header.pack()) |
recursion(path, outf) |
dentry = xstruct.create(DENTRY_NONE) |
dentry.kind = TMPFS_NONE |
dentry.fname_len = 0 |
outf.write(dentry.pack()) |
outf.seek(0) |
outf.write(struct.pack("<4sBBLQ", "HORD", 1, 1, header_size, aligned_size)) |
outf.close() |
if __name__ == '__main__': |
main() |
/branches/dd/tools/fix_symlinks.sh |
---|
1,5 → 1,3 |
#!/bin/bash |
# by Alf |
# This script solves malfunction of symlinks in cygwin |
# |
8,17 → 6,17 |
if uname | grep 'CYGWIN' > /dev/null; then |
echo "Good ... you have cygwin" |
echo "Good ... you have cygwin" |
else |
echo "Wrong. This script is only for cygwin" |
exit |
echo "Wrong. This script is only for cygwin" |
exit |
fi |
for linkName in `find . ! -iwholename '.*svn*' ! -type d -print`; do |
if head -n 1 $linkName | grep '^link' > /dev/null; then |
linkTarget=`head -n 1 $linkName | sed 's/^link //'` |
echo $linkName " -> " $linkTarget |
rm $linkName |
ln -s "$linkTarget" "$linkName" |
fi |
if head -n 1 $linkName | grep '^link' > /dev/null; then |
linkTarget=`head -n 1 $linkName | sed 's/^link //'` |
echo $linkName " -->" $linkTarget |
rm $linkName |
ln -s "$linkTarget" "$linkName" |
fi |
done |
/branches/dd/tools/config.py |
---|
1,7 → 1,6 |
#!/usr/bin/env python |
# |
# Copyright (c) 2006 Ondrej Palkovsky |
# Copyright (c) 2009 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
28,373 → 27,512 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
""" |
HelenOS configuration system |
HelenOS configuration script |
""" |
import sys |
import os |
import re |
import commands |
import xtui |
INPUT = sys.argv[1] |
MAKEFILE = 'Makefile.config' |
MACROS = 'config.h' |
DEFS = 'config.defs' |
OUTPUT = 'Makefile.config' |
TMPOUTPUT = 'Makefile.config.tmp' |
def read_defaults(fname, defaults): |
"Read saved values from last configuration run" |
inf = file(fname, 'r') |
for line in inf: |
res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line) |
if (res): |
defaults[res.group(1)] = res.group(2) |
inf.close() |
class DefaultDialog: |
"Wrapper dialog that tries to return default values" |
def __init__(self, dlg): |
self.dlg = dlg |
def check_condition(text, defaults, ask_names): |
"Check that the condition specified on input line is True (only CNF and DNF is supported)" |
ctype = 'cnf' |
if ((')|' in text) or ('|(' in text)): |
ctype = 'dnf' |
if (ctype == 'cnf'): |
conds = text.split('&') |
else: |
conds = text.split('|') |
for cond in conds: |
if (cond.startswith('(')) and (cond.endswith(')')): |
cond = cond[1:-1] |
inside = check_inside(cond, defaults, ctype) |
if (ctype == 'cnf') and (not inside): |
return False |
if (ctype == 'dnf') and (inside): |
return True |
if (ctype == 'cnf'): |
return True |
return False |
def set_title(self,text): |
self.dlg.set_title(text) |
def yesno(self, text, default=None): |
if default is not None: |
return default |
return self.dlg.yesno(text, default) |
def noyes(self, text, default=None): |
if default is not None: |
return default |
return self.dlg.noyes(text, default) |
def choice(self, text, choices, defopt=None): |
if defopt is not None: |
return choices[defopt][0] |
return self.dlg.choice(text, choices, defopt) |
def check_inside(text, defaults, ctype): |
"Check for condition" |
if (ctype == 'cnf'): |
conds = text.split('|') |
else: |
conds = text.split('&') |
for cond in conds: |
res = re.match(r'^(.*?)(!?=)(.*)$', cond) |
if (not res): |
raise RuntimeError("Invalid condition: %s" % cond) |
condname = res.group(1) |
oper = res.group(2) |
condval = res.group(3) |
if (not defaults.has_key(condname)): |
varval = '' |
else: |
varval = defaults[condname] |
if (varval == '*'): |
varval = 'y' |
if (ctype == 'cnf'): |
if (oper == '=') and (condval == varval): |
return True |
if (oper == '!=') and (condval != varval): |
return True |
else: |
if (oper == '=') and (condval != varval): |
return False |
if (oper == '!=') and (condval == varval): |
return False |
if (ctype == 'cnf'): |
return False |
return True |
class NoDialog: |
def __init__(self): |
self.printed = None |
self.title = 'HelenOS Configuration' |
def parse_config(fname, ask_names): |
"Parse configuration file" |
inf = file(fname, 'r') |
name = '' |
choices = [] |
for line in inf: |
if (line.startswith('!')): |
# Ask a question |
res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line) |
if (not res): |
raise RuntimeError("Weird line: %s" % line) |
cond = res.group(1) |
varname = res.group(2) |
vartype = res.group(3) |
ask_names.append((varname, vartype, name, choices, cond)) |
name = '' |
choices = [] |
continue |
if (line.startswith('@')): |
# Add new line into the 'choices' array |
res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line) |
if not res: |
raise RuntimeError("Bad line: %s" % line) |
choices.append((res.group(2), res.group(3))) |
continue |
if (line.startswith('%')): |
# Name of the option |
name = line[1:].strip() |
continue |
if ((line.startswith('#')) or (line == '\n')): |
# Comment or empty line |
continue |
raise RuntimeError("Unknown syntax: %s" % line) |
inf.close() |
def print_title(self): |
if not self.printed: |
sys.stdout.write("\n*** %s ***\n" % self.title) |
self.printed = True |
def yes_no(default): |
"Return '*' if yes, ' ' if no" |
if (default == 'y'): |
return '*' |
return ' ' |
def set_title(self, text): |
self.title = text |
self.printed = False |
def noyes(self, text, default=None): |
if not default: |
default = 'n' |
return self.yesno(text, default) |
def yesno(self, text, default=None): |
self.print_title() |
if default != 'n': |
default = 'y' |
while 1: |
sys.stdout.write("%s (y/n)[%s]: " % (text,default)) |
inp = sys.stdin.readline() |
if not inp: |
raise EOFError |
inp = inp.strip().lower() |
if not inp: |
return default |
if inp == 'y': |
return 'y' |
elif inp == 'n': |
return 'n' |
def subchoice(screen, name, choices, default): |
"Return choice of choices" |
maxkey = 0 |
for key, val in choices: |
length = len(key) |
if (length > maxkey): |
maxkey = length |
options = [] |
position = None |
cnt = 0 |
for key, val in choices: |
if ((default) and (key == default)): |
position = cnt |
options.append(" %-*s %s " % (maxkey, key, val)) |
cnt += 1 |
(button, value) = xtui.choice_window(screen, name, 'Choose value', options, position) |
if (button == 'cancel'): |
return None |
return choices[value][0] |
def _print_choice(self, text, choices, defopt): |
sys.stdout.write('%s:\n' % text) |
for i,(text,descr) in enumerate(choices): |
if descr is '': |
sys.stdout.write('\t%2d. %s\n' % (i, text)) |
else: |
sys.stdout.write('\t%2d. %s\n' % (i, descr)) |
if defopt is not None: |
sys.stdout.write('Enter choice number[%d]: ' % defopt) |
else: |
sys.stdout.write('Enter choice number: ') |
def check_choices(defaults, ask_names): |
"Check whether all accessible variables have a default" |
for varname, vartype, name, choices, cond in ask_names: |
if ((cond) and (not check_condition(cond, defaults, ask_names))): |
continue |
if (not defaults.has_key(varname)): |
return False |
return True |
def menu(self, text, choices, button, defopt=None): |
self.title = 'Main menu' |
menu = [] |
for key, descr in choices: |
txt = key + (45-len(key))*' ' + ': ' + descr |
menu.append((key, txt)) |
return self.choice(text, [button] + menu) |
def choice(self, text, choices, defopt=None): |
self.print_title() |
while 1: |
self._print_choice(text, choices, defopt) |
inp = sys.stdin.readline() |
if not inp: |
raise EOFError |
if not inp.strip(): |
if defopt is not None: |
return choices[defopt][0] |
continue |
try: |
number = int(inp.strip()) |
except ValueError: |
continue |
if number < 0 or number >= len(choices): |
continue |
return choices[number][0] |
def create_output(mkname, mcname, dfname, defaults, ask_names): |
"Create output configuration" |
revision = commands.getoutput('svnversion . 2> /dev/null') |
timestamp = commands.getoutput('date "+%Y-%m-%d %H:%M:%S"') |
outmk = file(mkname, 'w') |
outmc = file(mcname, 'w') |
outdf = file(dfname, 'w') |
outmk.write('#########################################\n') |
outmk.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n') |
outmk.write('#########################################\n\n') |
outmc.write('/***************************************\n') |
outmc.write(' * AUTO-GENERATED FILE, DO NOT EDIT!!! *\n') |
outmc.write(' ***************************************/\n\n') |
outdf.write('#########################################\n') |
outdf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n') |
outdf.write('#########################################\n\n') |
outdf.write('CONFIG_DEFS =') |
for varname, vartype, name, choices, cond in ask_names: |
if ((cond) and (not check_condition(cond, defaults, ask_names))): |
continue |
if (not defaults.has_key(varname)): |
default = '' |
else: |
default = defaults[varname] |
if (default == '*'): |
default = 'y' |
outmk.write('# %s\n%s = %s\n\n' % (name, varname, default)) |
if ((vartype == "y") or (vartype == "y/n") or (vartype == "n/y")): |
if (default == "y"): |
outmc.write('/* %s */\n#define %s\n\n' % (name, varname)) |
outdf.write(' -D%s' % varname) |
else: |
outmc.write('/* %s */\n#define %s %s\n#define %s_%s\n\n' % (name, varname, default, varname, default)) |
outdf.write(' -D%s=%s -D%s_%s' % (varname, default, varname, default)) |
outmk.write('REVISION = %s\n' % revision) |
outmk.write('TIMESTAMP = %s\n' % timestamp) |
outmc.write('#define REVISION %s\n' % revision) |
outmc.write('#define TIMESTAMP %s\n' % timestamp) |
outdf.write(' "-DREVISION=%s" "-DTIMESTAMP=%s"\n' % (revision, timestamp)) |
outmk.close() |
outmc.close() |
outdf.close() |
def eof_checker(fnc): |
def wrapper(self, *args, **kw): |
try: |
return fnc(self, *args, **kw) |
except EOFError: |
return getattr(self.bckdialog,fnc.func_name)(*args, **kw) |
return wrapper |
class Dialog(NoDialog): |
def __init__(self): |
NoDialog.__init__(self) |
self.dlgcmd = os.environ.get('DIALOG','dialog') |
self.title = '' |
self.backtitle = 'HelenOS Configuration' |
if os.system('%s --print-maxsize >/dev/null 2>&1' % self.dlgcmd) != 0: |
raise NotImplementedError |
self.bckdialog = NoDialog() |
def set_title(self,text): |
self.title = text |
self.bckdialog.set_title(text) |
def calldlg(self,*args,**kw): |
"Wrapper for calling 'dialog' program" |
indesc, outdesc = os.pipe() |
pid = os.fork() |
if not pid: |
os.close(2) |
os.dup(outdesc) |
os.close(indesc) |
dlgargs = [self.dlgcmd,'--title',self.title, |
'--backtitle', self.backtitle] |
for key,val in kw.items(): |
dlgargs.append('--'+key) |
dlgargs.append(val) |
dlgargs += args |
os.execlp(self.dlgcmd,*dlgargs) |
os.close(outdesc) |
try: |
errout = os.fdopen(indesc,'r') |
data = errout.read() |
errout.close() |
pid,status = os.wait() |
except: |
os.system('reset') # Reset terminal |
raise |
if not os.WIFEXITED(status): |
os.system('reset') # Reset terminal |
raise EOFError |
status = os.WEXITSTATUS(status) |
if status == 255: |
raise EOFError |
return status,data |
def yesno(self, text, default=None): |
if text[-1] not in ('?',':'): |
text = text + ':' |
width = '50' |
height = '5' |
if len(text) < 48: |
text = ' '*int(((48-len(text))/2)) + text |
else: |
width = '0' |
height = '0' |
if default == 'n': |
res,data = self.calldlg('--defaultno','--yesno',text,height,width) |
else: |
res,data = self.calldlg('--yesno',text,height,width) |
if res == 0: |
return 'y' |
return 'n' |
yesno = eof_checker(yesno) |
def menu(self, text, choices, button, defopt=None): |
self.title = 'Main menu' |
text = text + ':' |
width = '70' |
height = str(8 + len(choices)) |
args = [] |
for key,val in choices: |
args.append(key) |
args.append(val) |
kw = {} |
if defopt: |
kw['default-item'] = choices[defopt][0] |
res,data = self.calldlg('--ok-label','Change', |
'--extra-label',button[1], |
'--extra-button', |
'--menu',text,height,width, |
str(len(choices)),*args,**kw) |
if res == 3: |
return button[0] |
if res == 1: # Cancel |
sys.exit(1) |
elif res: |
print data |
raise EOFError |
return data |
menu = eof_checker(menu) |
def choice(self, text, choices, defopt=None): |
text = text + ':' |
width = '50' |
height = str(8 + len(choices)) |
args = [] |
for key,val in choices: |
args.append(key) |
args.append(val) |
kw = {} |
if defopt: |
kw['default-item'] = choices[defopt][0] |
res,data = self.calldlg('--nocancel','--menu',text,height,width, |
str(len(choices)),*args, **kw) |
if res: |
print data |
raise EOFError |
return data |
choice = eof_checker(choice) |
def read_defaults(fname,defaults): |
"Read saved values from last configuration run" |
f = file(fname,'r') |
for line in f: |
res = re.match(r'^(?:#!# )?([^#]\w*)\s*=\s*(.*?)\s*$', line) |
if res: |
defaults[res.group(1)] = res.group(2) |
f.close() |
def check_condition(text, defaults, asked_names): |
seen_vars = [ x[0] for x in asked_names ] |
ctype = 'cnf' |
if ')|' in text or '|(' in text: |
ctype = 'dnf' |
if ctype == 'cnf': |
conds = text.split('&') |
else: |
conds = text.split('|') |
for cond in conds: |
if cond.startswith('(') and cond.endswith(')'): |
cond = cond[1:-1] |
inside = check_inside(cond, defaults, ctype, seen_vars) |
if ctype == 'cnf' and not inside: |
return False |
if ctype == 'dnf' and inside: |
return True |
if ctype == 'cnf': |
return True |
return False |
def check_inside(text, defaults, ctype, seen_vars): |
""" |
Check that the condition specified on input line is True |
only CNF is supported |
""" |
if ctype == 'cnf': |
conds = text.split('|') |
else: |
conds = text.split('&') |
for cond in conds: |
res = re.match(r'^(.*?)(!?=)(.*)$', cond) |
if not res: |
raise RuntimeError("Invalid condition: %s" % cond) |
condname = res.group(1) |
oper = res.group(2) |
condval = res.group(3) |
if condname not in seen_vars: |
varval = '' |
## raise RuntimeError("Variable %s not defined before being asked." %\ |
## condname) |
elif not defaults.has_key(condname): |
raise RuntimeError("Condition var %s does not exist: %s" % \ |
(condname,text)) |
else: |
varval = defaults[condname] |
if ctype == 'cnf': |
if oper == '=' and condval == varval: |
return True |
if oper == '!=' and condval != varval: |
return True |
else: |
if oper== '=' and condval != varval: |
return False |
if oper== '!=' and condval == varval: |
return False |
if ctype=='cnf': |
return False |
return True |
def parse_config(input, output, dlg, defaults={}, askonly=None): |
"Parse configuration file and create Makefile.config on the fly" |
def ask_the_question(dialog): |
"Ask question based on the type of variables to ask" |
# This is quite a hack, this thingy is written just to |
# have access to local variables.. |
if vartype == 'y/n': |
return dialog.yesno(comment, default) |
elif vartype == 'n/y': |
return dialog.noyes(comment, default) |
elif vartype == 'choice': |
defopt = None |
if default is not None: |
for i,(key,val) in enumerate(choices): |
if key == default: |
defopt = i |
break |
return dialog.choice(comment, choices, defopt) |
else: |
raise RuntimeError("Bad method: %s" % vartype) |
f = file(input, 'r') |
outf = file(output, 'w') |
outf.write('#########################################\n') |
outf.write('## AUTO-GENERATED FILE, DO NOT EDIT!!! ##\n') |
outf.write('#########################################\n\n') |
asked_names = [] |
comment = '' |
default = None |
choices = [] |
for line in f: |
if line.startswith('%'): |
res = re.match(r'^%\s*(?:\[(.*?)\])?\s*(.*)$', line) |
if not res: |
raise RuntimeError('Invalid command: %s' % line) |
if res.group(1): |
if not check_condition(res.group(1), defaults, |
asked_names): |
continue |
args = res.group(2).strip().split(' ') |
cmd = args[0].lower() |
args = args[1:] |
if cmd == 'saveas': |
outf.write('%s = %s\n' % (args[1],defaults[args[0]])) |
elif cmd == 'shellcmd': |
varname = args[0] |
args = args[1:] |
for i,arg in enumerate(args): |
if arg.startswith('$'): |
args[i] = defaults[arg[1:]] |
data,status = commands.getstatusoutput(' '.join(args)) |
if status: |
raise RuntimeError('Error running: %s' % ' '.join(args)) |
outf.write('%s = %s\n' % (varname,data.strip())) |
continue |
if line.startswith('!'): |
# Ask a question |
res = re.search(r'!\s*(?:\[(.*?)\])?\s*([^\s]+)\s*\((.*)\)\s*$', line) |
if not res: |
raise RuntimeError("Weird line: %s" % line) |
varname = res.group(2) |
vartype = res.group(3) |
default = defaults.get(varname,None) |
if res.group(1): |
if not check_condition(res.group(1), defaults, |
asked_names): |
if default is not None: |
outf.write('#!# %s = %s\n' % (varname, default)) |
# Clear cumulated values |
comment = '' |
default = None |
choices = [] |
continue |
asked_names.append((varname,comment)) |
if default is None or not askonly or askonly == varname: |
default = ask_the_question(dlg) |
else: |
default = ask_the_question(DefaultDialog(dlg)) |
outf.write('%s = %s\n' % (varname, default)) |
# Remeber the selected value |
defaults[varname] = default |
# Clear cumulated values |
comment = '' |
default = None |
choices = [] |
continue |
if line.startswith('@'): |
# Add new line into the 'choice array' |
res = re.match(r'@\s*(?:\[(.*?)\])?\s*"(.*?)"\s*(.*)$', line) |
if not res: |
raise RuntimeError("Bad line: %s" % line) |
if res.group(1): |
if not check_condition(res.group(1),defaults, |
asked_names): |
continue |
choices.append((res.group(2), res.group(3))) |
continue |
# All other things print to output file |
outf.write(line) |
if re.match(r'^#[^#]', line): |
# Last comment before question will be displayed to the user |
comment = line[1:].strip() |
elif line.startswith('## '): |
# Set title of the dialog window |
dlg.set_title(line[2:].strip()) |
outf.write('\n') |
outf.write('REVISION = %s\n' % commands.getoutput('svnversion . 2> /dev/null')) |
outf.write('TIMESTAMP = %s\n' % commands.getoutput('date "+%Y-%m-%d %H:%M:%S"')) |
outf.close() |
f.close() |
return asked_names |
def main(): |
defaults = {} |
ask_names = [] |
defaults = {} |
try: |
dlg = Dialog() |
except NotImplementedError: |
dlg = NoDialog() |
if len(sys.argv) >= 3 and sys.argv[2]=='default': |
defmode = True |
else: |
defmode = False |
# Default run will update the configuration file |
# with newest options |
if os.path.exists(OUTPUT): |
read_defaults(OUTPUT, defaults) |
# Get ARCH from command line if specified |
if len(sys.argv) >= 4: |
defaults['ARCH'] = sys.argv[3] |
defaults['PLATFORM'] = sys.argv[3] |
# Parse configuration file |
parse_config(INPUT, ask_names) |
# Get COMPILER from command line if specified |
if len(sys.argv) >= 5: |
defaults['COMPILER'] = sys.argv[4] |
# Read defaults from previous run |
if os.path.exists(MAKEFILE): |
read_defaults(MAKEFILE, defaults) |
# Get CONFIG_DEBUG from command line if specified |
if len(sys.argv) >= 6: |
defaults['CONFIG_DEBUG'] = sys.argv[5] |
# Default mode: only check defaults and regenerate configuration |
if ((len(sys.argv) >= 3) and (sys.argv[2] == 'default')): |
if (check_choices(defaults, ask_names)): |
create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names) |
return 0 |
# Check mode: only check defaults |
if ((len(sys.argv) >= 3) and (sys.argv[2] == 'check')): |
if (check_choices(defaults, ask_names)): |
return 0 |
return 1 |
screen = xtui.screen_init() |
try: |
selname = None |
while True: |
# Cancel out all defaults which have to be deduced |
for varname, vartype, name, choices, cond in ask_names: |
if ((vartype == 'y') and (defaults.has_key(varname)) and (defaults[varname] == '*')): |
defaults[varname] = None |
options = [] |
opt2row = {} |
position = None |
cnt = 0 |
for varname, vartype, name, choices, cond in ask_names: |
if ((cond) and (not check_condition(cond, defaults, ask_names))): |
continue |
if (varname == selname): |
position = cnt |
if (not defaults.has_key(varname)): |
default = None |
else: |
default = defaults[varname] |
if (vartype == 'choice'): |
# Check if the default is an acceptable value |
if ((default) and (not default in [choice[0] for choice in choices])): |
default = None |
defaults.pop(varname) |
# If there is just one option, use it |
if (len(choices) == 1): |
defaults[varname] = choices[0][0] |
continue |
if (default == None): |
options.append("? %s --> " % name) |
else: |
options.append(" %s [%s] --> " % (name, default)) |
elif (vartype == 'y'): |
defaults[varname] = '*' |
continue |
elif (vartype == 'y/n'): |
if (default == None): |
default = 'y' |
defaults[varname] = default |
options.append(" <%s> %s " % (yes_no(default), name)) |
elif (vartype == 'n/y'): |
if (default == None): |
default = 'n' |
defaults[varname] = default |
options.append(" <%s> %s " % (yes_no(default), name)) |
else: |
raise RuntimeError("Unknown variable type: %s" % vartype) |
opt2row[cnt] = (varname, vartype, name, choices) |
cnt += 1 |
(button, value) = xtui.choice_window(screen, 'HelenOS configuration', 'Choose configuration option', options, position) |
if (button == 'cancel'): |
return 'Configuration canceled' |
if (not opt2row.has_key(value)): |
raise RuntimeError("Error selecting value: %s" % value) |
(selname, seltype, name, choices) = opt2row[value] |
if (not defaults.has_key(selname)): |
default = None |
else: |
default = defaults[selname] |
if (button == 'done'): |
if (check_choices(defaults, ask_names)): |
break |
else: |
xtui.error_dialog(screen, 'Error', 'Some options have still undefined values. These options are marked with the "?" sign.') |
continue |
if (seltype == 'choice'): |
defaults[selname] = subchoice(screen, name, choices, default) |
elif ((seltype == 'y/n') or (seltype == 'n/y')): |
if (defaults[selname] == 'y'): |
defaults[selname] = 'n' |
else: |
defaults[selname] = 'y' |
finally: |
xtui.screen_done(screen) |
create_output(MAKEFILE, MACROS, DEFS, defaults, ask_names) |
return 0 |
# Get MACHINE/IMAGE from command line if specified |
if len(sys.argv) >= 7: |
defaults['MACHINE'] = sys.argv[6] |
defaults['IMAGE'] = sys.argv[6] |
# Dry run only with defaults |
varnames = parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults) |
# If not in default mode, present selection of all possibilities |
if not defmode: |
defopt = 0 |
while 1: |
# varnames contains variable names that were in the |
# last question set |
choices = [ (x[1],defaults[x[0]]) for x in varnames ] |
res = dlg.menu('Configuration',choices,('save','Save'),defopt) |
if res == 'save': |
parse_config(INPUT, TMPOUTPUT, DefaultDialog(dlg), defaults) |
break |
# transfer description back to varname |
for i,(vname,descr) in enumerate(varnames): |
if res == descr: |
defopt = i |
break |
# Ask the user a simple question, produce output |
# as if the user answered all the other questions |
# with default answer |
varnames = parse_config(INPUT, TMPOUTPUT, dlg, defaults, |
askonly=varnames[i][0]) |
if os.path.exists(OUTPUT): |
os.unlink(OUTPUT) |
os.rename(TMPOUTPUT, OUTPUT) |
if not defmode and dlg.yesno('Rebuild everything?') == 'y': |
os.execlp('make','make','clean','build') |
if __name__ == '__main__': |
sys.exit(main()) |
main() |
/branches/dd/kernel/generic/include/udebug/udebug_ops.h |
---|
File deleted |
/branches/dd/kernel/generic/include/udebug/udebug_ipc.h |
---|
File deleted |
/branches/dd/kernel/generic/include/udebug/udebug.h |
---|
File deleted |
/branches/dd/kernel/generic/include/string.h |
---|
File deleted |
/branches/dd/kernel/generic/include/ipc/kbox.h |
---|
File deleted |
/branches/dd/kernel/generic/include/ipc/ipc.h |
---|
195,12 → 195,6 |
*/ |
#define IPC_M_DATA_READ 7 |
/** Debug the recipient. |
* - ARG1 - specifies the debug method (from udebug_method_t) |
* - other arguments are specific to the debug method |
*/ |
#define IPC_M_DEBUG_ALL 8 |
/* Well-known methods */ |
#define IPC_M_LAST_SYSTEM 511 |
#define IPC_M_PING 512 |
287,13 → 281,6 |
/** Buffer for IPC_M_DATA_WRITE and IPC_M_DATA_READ. */ |
uint8_t *buffer; |
/* |
* The forward operation can masquerade the caller phone. For those |
* cases, we must keep it aside so that the answer is processed |
* correctly. |
*/ |
phone_t *caller_phone; |
} call_t; |
extern void ipc_init(void); |
300,7 → 287,7 |
extern call_t * ipc_wait_for_call(answerbox_t *, uint32_t, int); |
extern void ipc_answer(answerbox_t *, call_t *); |
extern int ipc_call(phone_t *, call_t *); |
extern int ipc_call_sync(phone_t *, call_t *); |
extern void ipc_call_sync(phone_t *, call_t *); |
extern void ipc_phone_init(phone_t *); |
extern void ipc_phone_connect(phone_t *, answerbox_t *); |
extern void ipc_call_free(call_t *); |
313,8 → 300,6 |
extern int ipc_phone_hangup(phone_t *); |
extern void ipc_backsend_err(phone_t *, call_t *, unative_t); |
extern void ipc_print_task(task_id_t); |
extern void ipc_answerbox_slam_phones(answerbox_t *, bool); |
extern void ipc_cleanup_call_list(link_t *); |
extern answerbox_t *ipc_phone_0; |
/branches/dd/kernel/generic/include/ipc/sysipc.h |
---|
53,13 → 53,10 |
int nonblocking); |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode); |
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, |
ipc_data_t *data, int mode); |
unative_t sys_ipc_hangup(int phoneid); |
unative_t sys_ipc_register_irq(inr_t inr, devno_t devno, unative_t method, |
irq_code_t *ucode); |
unative_t sys_ipc_unregister_irq(inr_t inr, devno_t devno); |
unative_t sys_ipc_connect_kbox(sysarg64_t *task_id); |
#endif |
/branches/dd/kernel/generic/include/ipc/irq.h |
---|
36,7 → 36,7 |
#define KERN_IPC_IRQ_H_ |
/** Maximum length of IPC IRQ program */ |
#define IRQ_MAX_PROG_SIZE 20 |
#define IRQ_MAX_PROG_SIZE 10 |
#include <ipc/ipc.h> |
#include <ddi/irq.h> |
43,21 → 43,16 |
#include <arch/types.h> |
#include <adt/list.h> |
extern int ipc_irq_register(answerbox_t *, inr_t, devno_t, unative_t, |
irq_code_t *); |
extern int ipc_irq_register(answerbox_t *box, inr_t inr, devno_t devno, |
unative_t method, irq_code_t *ucode); |
extern void ipc_irq_send_notif(irq_t *irq); |
extern void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno); |
extern void ipc_irq_cleanup(answerbox_t *box); |
extern irq_ownership_t ipc_irq_top_half_claim(irq_t *); |
extern void ipc_irq_top_half_handler(irq_t *); |
extern int ipc_irq_unregister(answerbox_t *, inr_t, devno_t); |
extern void ipc_irq_cleanup(answerbox_t *); |
/* |
* User friendly wrappers for ipc_irq_send_msg(). They are in the form |
* ipc_irq_send_msg_m(), where m is the number of payload arguments. |
*/ |
#define ipc_irq_send_msg_0(irq) \ |
ipc_irq_send_msg((irq), 0, 0, 0, 0, 0) |
#define ipc_irq_send_msg_1(irq, a1) \ |
ipc_irq_send_msg((irq), (a1), 0, 0, 0, 0) |
#define ipc_irq_send_msg_2(irq, a1, a2) \ |
69,8 → 64,8 |
#define ipc_irq_send_msg_5(irq, a1, a2, a3, a4, a5) \ |
ipc_irq_send_msg((irq), (a1), (a2), (a3), (a4), (a5)) |
extern void ipc_irq_send_msg(irq_t *, unative_t, unative_t, unative_t, unative_t, |
unative_t); |
extern void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, |
unative_t a3, unative_t a4, unative_t a5); |
#endif |
/branches/dd/kernel/generic/include/proc/program.h |
---|
File deleted |
/branches/dd/kernel/generic/include/proc/task.h |
---|
52,11 → 52,7 |
#include <arch/cpu.h> |
#include <mm/tlb.h> |
#include <proc/scheduler.h> |
#include <udebug/udebug.h> |
#include <ipc/kbox.h> |
#define TASK_NAME_BUFLEN 20 |
struct thread; |
/** Task structure. */ |
70,8 → 66,8 |
* threads. |
*/ |
SPINLOCK_DECLARE(lock); |
char name[TASK_NAME_BUFLEN]; |
char *name; |
/** List of threads contained in this task. */ |
link_t th_head; |
/** Address space. */ |
97,15 → 93,7 |
* certain extent. |
*/ |
atomic_t active_calls; |
#ifdef CONFIG_UDEBUG |
/** Debugging stuff. */ |
udebug_task_t udebug; |
/** Kernel answerbox. */ |
kbox_t kb; |
#endif |
/** Architecture specific task data. */ |
task_arch_t arch; |
128,6 → 116,7 |
extern void task_done(void); |
extern task_t *task_create(as_t *as, char *name); |
extern void task_destroy(task_t *t); |
extern task_t *task_run_program(void *program_addr, char *name); |
extern task_t *task_find_by_id(task_id_t id); |
extern int task_kill(task_id_t id); |
extern uint64_t task_get_accounting(task_t *t); |
144,7 → 133,6 |
#endif |
extern unative_t sys_task_get_id(task_id_t *uspace_task_id); |
extern unative_t sys_task_set_name(const char *uspace_name, size_t name_len); |
#endif |
/branches/dd/kernel/generic/include/proc/thread.h |
---|
46,7 → 46,6 |
#include <arch/cpu.h> |
#include <mm/tlb.h> |
#include <proc/uarg.h> |
#include <udebug/udebug.h> |
#define THREAD_STACK_SIZE STACK_SIZE |
#define THREAD_NAME_BUFLEN 20 |
204,12 → 203,6 |
/** Thread's kernel stack. */ |
uint8_t *kstack; |
#ifdef CONFIG_UDEBUG |
/** Debugging stuff */ |
udebug_thread_t udebug; |
#endif |
} thread_t; |
/** Thread list lock. |
259,8 → 252,7 |
extern slab_cache_t *fpu_context_slab; |
/* Thread syscall prototypes. */ |
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, |
char *uspace_name, size_t name_len, thread_id_t *uspace_thread_id); |
extern unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, thread_id_t *uspace_thread_id); |
extern unative_t sys_thread_exit(int uspace_status); |
extern unative_t sys_thread_get_id(thread_id_t *uspace_thread_id); |
/branches/dd/kernel/generic/include/byteorder.h |
---|
51,14 → 51,6 |
#define uint32_t_be2host(n) (n) |
#define uint64_t_be2host(n) (n) |
#define host2uint16_t_le(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_le(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_le(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_be(n) (n) |
#define host2uint32_t_be(n) (n) |
#define host2uint64_t_be(n) (n) |
#else |
#define uint16_t_le2host(n) (n) |
69,14 → 61,6 |
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n) |
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_le(n) (n) |
#define host2uint32_t_le(n) (n) |
#define host2uint64_t_le(n) (n) |
#define host2uint16_t_be(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_be(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_be(n) uint64_t_byteorder_swap(n) |
#endif |
static inline uint64_t uint64_t_byteorder_swap(uint64_t n) |
/branches/dd/kernel/generic/include/lib/elf.h |
---|
114,8 → 114,7 |
#define EE_MEMORY 2 /* Cannot allocate address space */ |
#define EE_INCOMPATIBLE 3 /* ELF image is not compatible with current architecture */ |
#define EE_UNSUPPORTED 4 /* Non-supported ELF (e.g. dynamic ELFs) */ |
#define EE_LOADER 5 /* The image is actually a program loader */ |
#define EE_IRRECOVERABLE 6 |
#define EE_IRRECOVERABLE 5 |
/** |
* ELF section types |
339,10 → 338,6 |
extern char *elf_error(unsigned int rc); |
/* Interpreter string used to recognize the program loader */ |
#define ELF_INTERP_ZSTR "kernel" |
#define ELF_INTERP_ZLEN sizeof(ELF_INTERP_ZSTR) |
#endif |
/** @} |
/branches/dd/kernel/generic/include/lib/rd.h |
---|
66,18 → 66,16 |
#define RE_UNSUPPORTED 2 /* Non-supported image (e.g. wrong version) */ |
/** RAM disk header */ |
struct rd_header { |
typedef struct { |
uint8_t magic[RD_MAGIC_SIZE]; |
uint8_t version; |
uint8_t data_type; |
uint32_t header_size; |
uint64_t data_size; |
} __attribute__ ((packed)); |
} rd_header; |
typedef struct rd_header rd_header_t; |
extern int init_rd(rd_header * addr, size_t size); |
extern int init_rd(rd_header_t *addr, size_t size); |
#endif |
/** @} |
/branches/dd/kernel/generic/include/lib/objc.h |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_OBJC_H_ |
#define KERN_OBJC_H_ |
extern id class_create_instance(Class _class); |
extern id object_dispose(id object); |
@interface base_t { |
Class isa; |
} |
+ (id) new; |
- (id) free; |
@end |
#endif |
/branches/dd/kernel/generic/include/lib/objc_ext.h |
---|
0,0 → 1,64 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_OBJC_EXT_H_ |
#define KERN_OBJC_EXT_H_ |
#include <arch/types.h> |
#include <arch/arg.h> |
extern void *stderr; |
extern void __assert_fail(const char *assertion, const char *file, unsigned int line, const char *function); |
extern void abort(void); |
extern void *fopen(const char *path, const char *mode); |
extern size_t fread(void *ptr, size_t size, size_t nmemb, void *stream); |
extern size_t fwrite(const void *ptr, size_t size, size_t nmemb, void *stream); |
extern int fflush(void *stream); |
extern int feof(void *stream); |
extern int fclose(void *stream); |
extern int vfprintf(void *stream, const char *format, va_list ap); |
extern int sscanf(const char *str, const char *format, ...); |
extern const unsigned short **__ctype_b_loc(void); |
extern long int __strtol_internal(const char *__nptr, char **__endptr, int __base, int __group); |
extern void *memset(void *s, int c, size_t n); |
extern void *calloc(size_t nmemb, size_t size); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/generic/include/mm/slab.h |
---|
53,13 → 53,12 |
#define SLAB_INSIDE_SIZE (PAGE_SIZE >> 3) |
/** Maximum wasted space we allow for cache */ |
#define SLAB_MAX_BADNESS(cache) \ |
(((unsigned int) PAGE_SIZE << (cache)->order) >> 2) |
#define SLAB_MAX_BADNESS(cache) (((unsigned int) PAGE_SIZE << (cache)->order) >> 2) |
/* slab_reclaim constants */ |
/** Reclaim all possible memory, because we are in memory stress */ |
#define SLAB_RECLAIM_ALL 0x01 |
#define SLAB_RECLAIM_ALL 0x1 |
/* cache_create flags */ |
100,7 → 99,7 |
int flags; |
/* Computed values */ |
uint8_t order; /**< Order of frames to be allocated */ |
uint8_t order; /**< Order of frames to be allocated */ |
unsigned int objects; /**< Number of objects that fit in */ |
/* Statistics */ |
122,13 → 121,14 |
slab_mag_cache_t *mag_cache; |
} slab_cache_t; |
extern slab_cache_t *slab_cache_create(char *, size_t, size_t, |
int (*)(void *, int), int (*)(void *), int); |
extern void slab_cache_destroy(slab_cache_t *); |
extern slab_cache_t * slab_cache_create(char *name, size_t size, size_t align, |
int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj), |
int flags); |
extern void slab_cache_destroy(slab_cache_t *cache); |
extern void * slab_alloc(slab_cache_t *, int); |
extern void slab_free(slab_cache_t *, void *); |
extern count_t slab_reclaim(int); |
extern void * slab_alloc(slab_cache_t *cache, int flags); |
extern void slab_free(slab_cache_t *cache, void *obj); |
extern count_t slab_reclaim(int flags); |
/* slab subsytem initialization */ |
extern void slab_cache_init(void); |
138,9 → 138,9 |
extern void slab_print_list(void); |
/* malloc support */ |
extern void *malloc(unsigned int, int); |
extern void *realloc(void *, unsigned int, int); |
extern void free(void *); |
extern void * malloc(unsigned int size, int flags); |
extern void * realloc(void *ptr, unsigned int size, int flags); |
extern void free(void *ptr); |
#endif |
/** @} |
/branches/dd/kernel/generic/include/mm/as.h |
---|
53,6 → 53,10 |
#include <adt/btree.h> |
#include <lib/elf.h> |
#ifdef __OBJC__ |
#include <lib/objc.h> |
#endif |
/** |
* Defined to be true if user address space and kernel address space shadow each |
* other. |
80,6 → 84,47 |
/** The page fault was caused by memcpy_from_uspace() or memcpy_to_uspace(). */ |
#define AS_PF_DEFER 2 |
#ifdef __OBJC__ |
@interface as_t : base_t { |
@public |
/** Protected by asidlock. */ |
link_t inactive_as_with_asid_link; |
/** |
* Number of processors on wich is this address space active. |
* Protected by asidlock. |
*/ |
count_t cpu_refcount; |
/** |
* Address space identifier. |
* Constant on architectures that do not support ASIDs. |
* Protected by asidlock. |
*/ |
asid_t asid; |
/** Number of references (i.e tasks that reference this as). */ |
atomic_t refcount; |
mutex_t lock; |
/** B+tree of address space areas. */ |
btree_t as_area_btree; |
/** Non-generic content. */ |
as_genarch_t genarch; |
/** Architecture specific content. */ |
as_arch_t arch; |
} |
+ (pte_t *) page_table_create: (int) flags; |
+ (void) page_table_destroy: (pte_t *) page_table; |
- (void) page_table_lock: (bool) _lock; |
- (void) page_table_unlock: (bool) unlock; |
@end |
#else |
/** Address space structure. |
* |
* as_t contains the list of as_areas of userspace accessible |
123,6 → 168,7 |
void (* page_table_lock)(as_t *as, bool lock); |
void (* page_table_unlock)(as_t *as, bool unlock); |
} as_operations_t; |
#endif |
/** |
* This structure contains information associated with the shared address space |
203,7 → 249,10 |
extern as_t *AS_KERNEL; |
#ifndef __OBJC__ |
extern as_operations_t *as_operations; |
#endif |
extern link_t inactive_as_with_asid_head; |
extern void as_init(void); |
220,7 → 269,6 |
extern int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags); |
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask); |
extern int as_area_change_flags(as_t *as, int flags, uintptr_t address); |
extern int as_area_get_flags(as_area_t *area); |
extern bool as_area_check_access(as_area_t *area, pf_access_t access); |
251,19 → 299,11 |
extern mem_backend_t elf_backend; |
extern mem_backend_t phys_backend; |
/** |
* This flags is passed when running the loader, otherwise elf_load() |
* would return with a EE_LOADER error code. |
*/ |
#define ELD_F_NONE 0 |
#define ELD_F_LOADER 1 |
extern unsigned int elf_load(elf_header_t *header, as_t *as); |
extern unsigned int elf_load(elf_header_t *header, as_t *as, int flags); |
/* Address space area related syscalls. */ |
extern unative_t sys_as_area_create(uintptr_t address, size_t size, int flags); |
extern unative_t sys_as_area_resize(uintptr_t address, size_t size, int flags); |
extern unative_t sys_as_area_change_flags(uintptr_t address, int flags); |
extern unative_t sys_as_area_destroy(uintptr_t address); |
/* Introspection functions. */ |
/branches/dd/kernel/generic/include/mm/frame.h |
---|
38,82 → 38,35 |
#include <arch/types.h> |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <mm/buddy.h> |
#include <synch/spinlock.h> |
#include <arch/mm/page.h> |
#include <arch/mm/frame.h> |
#define ONE_FRAME 0 |
#define TWO_FRAMES 1 |
#define FOUR_FRAMES 2 |
#define ONE_FRAME 0 |
#define TWO_FRAMES 1 |
#define FOUR_FRAMES 2 |
#ifdef ARCH_STACK_FRAMES |
#define STACK_FRAMES ARCH_STACK_FRAMES |
#define STACK_FRAMES ARCH_STACK_FRAMES |
#else |
#define STACK_FRAMES ONE_FRAME |
#define STACK_FRAMES ONE_FRAME |
#endif |
/** Maximum number of zones in the system. */ |
#define ZONES_MAX 32 |
/** Maximum number of zones in system. */ |
#define ZONES_MAX 16 |
typedef uint8_t frame_flags_t; |
/** If possible, merge with neighbouring zones. */ |
#define ZONE_JOIN 0x1 |
/** Convert the frame address to kernel VA. */ |
#define FRAME_KA 0x01 |
/** Convert the frame address to kernel va. */ |
#define FRAME_KA 0x1 |
/** Do not panic and do not sleep on failure. */ |
#define FRAME_ATOMIC 0x02 |
#define FRAME_ATOMIC 0x2 |
/** Do not start reclaiming when no free memory. */ |
#define FRAME_NO_RECLAIM 0x04 |
#define FRAME_NO_RECLAIM 0x4 |
typedef uint8_t zone_flags_t; |
/** Available zone (free for allocation) */ |
#define ZONE_AVAILABLE 0x00 |
/** Zone is reserved (not available for allocation) */ |
#define ZONE_RESERVED 0x08 |
/** Zone is used by firmware (not available for allocation) */ |
#define ZONE_FIRMWARE 0x10 |
/** Currently there is no equivalent zone flags |
for frame flags */ |
#define FRAME_TO_ZONE_FLAGS(frame_flags) 0 |
typedef struct { |
count_t refcount; /**< Tracking of shared frames */ |
uint8_t buddy_order; /**< Buddy system block order */ |
link_t buddy_link; /**< Link to the next free block inside |
one order */ |
void *parent; /**< If allocated by slab, this points there */ |
} frame_t; |
typedef struct { |
pfn_t base; /**< Frame_no of the first frame |
in the frames array */ |
count_t count; /**< Size of zone */ |
count_t free_count; /**< Number of free frame_t |
structures */ |
count_t busy_count; /**< Number of busy frame_t |
structures */ |
zone_flags_t flags; /**< Type of the zone */ |
frame_t *frames; /**< Array of frame_t structures |
in this zone */ |
buddy_system_t *buddy_system; /**< Buddy system for the zone */ |
} zone_t; |
/* |
* The zoneinfo.lock must be locked when accessing zoneinfo structure. |
* Some of the attributes in zone_t structures are 'read-only' |
*/ |
typedef struct { |
SPINLOCK_DECLARE(lock); |
count_t count; |
zone_t info[ZONES_MAX]; |
} zones_t; |
extern zones_t zones; |
static inline uintptr_t PFN2ADDR(pfn_t frame) |
{ |
return (uintptr_t) (frame << FRAME_WIDTH); |
136,37 → 89,31 |
return (size_t) (frames << FRAME_WIDTH); |
} |
static inline bool zone_flags_available(zone_flags_t flags) |
{ |
return ((flags & (ZONE_RESERVED | ZONE_FIRMWARE)) == 0); |
} |
#define IS_BUDDY_ORDER_OK(index, order) \ |
((~(((unative_t) -1) << (order)) & (index)) == 0) |
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \ |
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \ |
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \ |
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 0) |
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \ |
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x1) == 1) |
#define IS_BUDDY_ORDER_OK(index, order) \ |
((~(((unative_t) -1) << (order)) & (index)) == 0) |
#define IS_BUDDY_LEFT_BLOCK(zone, frame) \ |
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0) |
#define IS_BUDDY_RIGHT_BLOCK(zone, frame) \ |
(((frame_index((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1) |
#define IS_BUDDY_LEFT_BLOCK_ABS(zone, frame) \ |
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 0) |
#define IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame) \ |
(((frame_index_abs((zone), (frame)) >> (frame)->buddy_order) & 0x01) == 1) |
#define frame_alloc(order, flags) \ |
frame_alloc_generic(order, flags, NULL) |
#define frame_alloc(order, flags) \ |
frame_alloc_generic(order, flags, NULL) |
extern void frame_init(void); |
extern void *frame_alloc_generic(uint8_t, frame_flags_t, count_t *); |
extern void frame_free(uintptr_t); |
extern void frame_reference_add(pfn_t); |
extern void *frame_alloc_generic(uint8_t order, int flags, unsigned int *pzone); |
extern void frame_free(uintptr_t frame); |
extern void frame_reference_add(pfn_t pfn); |
extern count_t find_zone(pfn_t frame, count_t count, count_t hint); |
extern count_t zone_create(pfn_t, count_t, pfn_t, zone_flags_t); |
extern void *frame_get_parent(pfn_t, count_t); |
extern void frame_set_parent(pfn_t, void *, count_t); |
extern void frame_mark_unavailable(pfn_t, count_t); |
extern uintptr_t zone_conf_size(count_t); |
extern bool zone_merge(count_t, count_t); |
extern int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags); |
extern void *frame_get_parent(pfn_t frame, unsigned int hint); |
extern void frame_set_parent(pfn_t frame, void *data, unsigned int hint); |
extern void frame_mark_unavailable(pfn_t start, count_t count); |
extern uintptr_t zone_conf_size(count_t count); |
extern void zone_merge(unsigned int z1, unsigned int z2); |
extern void zone_merge_all(void); |
extern uint64_t zone_total_size(void); |
174,7 → 121,7 |
* Console functions |
*/ |
extern void zone_print_list(void); |
extern void zone_print_one(count_t); |
extern void zone_print_one(unsigned int znum); |
#endif |
/branches/dd/kernel/generic/include/mm/page.h |
---|
39,10 → 39,15 |
#include <mm/as.h> |
#include <memstr.h> |
/** |
* Macro for computing page color. |
*/ |
#define PAGE_COLOR(va) (((va) >> PAGE_WIDTH) & ((1 << PAGE_COLOR_BITS) - 1)) |
/** Operations to manipulate page mappings. */ |
typedef struct { |
void (* mapping_insert)(as_t *as, uintptr_t page, uintptr_t frame, |
int flags); |
int flags); |
void (* mapping_remove)(as_t *as, uintptr_t page); |
pte_t *(* mapping_find)(as_t *as, uintptr_t page); |
} page_mapping_operations_t; |
59,7 → 64,6 |
extern pte_t *page_table_create(int flags); |
extern void page_table_destroy(pte_t *page_table); |
extern void map_structure(uintptr_t s, size_t size); |
extern uintptr_t hw_map(uintptr_t physaddr, size_t size); |
#endif |
/branches/dd/kernel/generic/include/mm/buddy.h |
---|
66,6 → 66,7 |
void (*mark_available)(struct buddy_system *, link_t *); |
/** Find parent of block that has given order */ |
link_t *(* find_block)(struct buddy_system *, link_t *, uint8_t); |
void (* print_id)(struct buddy_system *, link_t *); |
} buddy_system_operations_t; |
typedef struct buddy_system { |
77,13 → 78,14 |
void *data; |
} buddy_system_t; |
extern void buddy_system_create(buddy_system_t *, uint8_t, |
buddy_system_operations_t *, void *); |
extern link_t *buddy_system_alloc(buddy_system_t *, uint8_t); |
extern bool buddy_system_can_alloc(buddy_system_t *, uint8_t); |
extern void buddy_system_free(buddy_system_t *, link_t *); |
extern size_t buddy_conf_size(size_t); |
extern link_t *buddy_system_alloc_block(buddy_system_t *, link_t *); |
extern void buddy_system_create(buddy_system_t *b, uint8_t max_order, |
buddy_system_operations_t *op, void *data); |
extern link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i); |
extern bool buddy_system_can_alloc(buddy_system_t *b, uint8_t order); |
extern void buddy_system_free(buddy_system_t *b, link_t *block); |
extern void buddy_system_structure_print(buddy_system_t *b, size_t elem_size); |
extern size_t buddy_conf_size(int max_order); |
extern link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block); |
#endif |
/branches/dd/kernel/generic/include/config.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
38,16 → 38,15 |
#include <arch/types.h> |
#include <arch/mm/page.h> |
#define STACK_SIZE PAGE_SIZE |
#define STACK_SIZE PAGE_SIZE |
#define CONFIG_INIT_TASKS 32 |
#define CONFIG_MEMORY_SIZE (8 * 1024 * 1024) |
#define CONFIG_TASK_NAME_BUFLEN 32 |
#define CONFIG_INIT_TASKS 32 |
typedef struct { |
uintptr_t addr; |
size_t size; |
char name[CONFIG_TASK_NAME_BUFLEN]; |
} init_task_t; |
typedef struct { |
66,14 → 65,14 |
} ballocs_t; |
typedef struct { |
count_t cpu_count; /**< Number of processors detected. */ |
volatile count_t cpu_active; /**< Number of processors that are up and running. */ |
count_t cpu_count; /**< Number of processors detected. */ |
volatile count_t cpu_active; /**< Number of processors that are up and running. */ |
uintptr_t base; |
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */ |
size_t kernel_size; /**< Size of memory in bytes taken by kernel and stack */ |
uintptr_t stack_base; /**< Base adddress of initial stack */ |
size_t stack_size; /**< Size of initial stack */ |
uintptr_t stack_base; /**< Base adddress of initial stack */ |
size_t stack_size; /**< Size of initial stack */ |
} config_t; |
extern config_t config; |
/branches/dd/kernel/generic/include/macros.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
37,25 → 37,22 |
#include <arch/types.h> |
#define isdigit(d) (((d) >= '0') && ((d) <= '9')) |
#define islower(c) (((c) >= 'a') && ((c) <= 'z')) |
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z')) |
#define isalpha(c) (is_lower((c)) || is_upper((c))) |
#define isalphanum(c) (is_alpha((c)) || is_digit((c))) |
#define isspace(c) \ |
(((c) == ' ') || ((c) == '\t') || ((c) == '\n') || ((c) == '\r')) |
#define isdigit(d) (((d) >= '0') && ((d) <= '9')) |
#define islower(c) (((c) >= 'a') && ((c) <= 'z')) |
#define isupper(c) (((c) >= 'A') && ((c) <= 'Z')) |
#define isalpha(c) (is_lower(c) || is_upper(c)) |
#define isalphanum(c) (is_alpha(c) || is_digit(c)) |
#define isspace(c) (((c) == ' ') || ((c) == '\t') || ((c) == '\n') || \ |
((c) == '\r')) |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
#define max(a, b) ((a) > (b) ? (a) : (b)) |
#define min(a,b) ((a) < (b) ? (a) : (b)) |
#define max(a,b) ((a) > (b) ? (a) : (b)) |
#define min3(a, b, c) ((a) < (b) ? (min(a, c)) : (min(b, c))) |
#define max3(a, b, c) ((a) > (b) ? (max(a, c)) : (max(b, c))) |
/** Return true if the intervals overlap. |
/** Return true if the interlvals overlap. |
* |
* @param s1 Start address of the first interval. |
* @param s1 Start address of the first interval. |
* @param sz1 Size of the first interval. |
* @param s2 Start address of the second interval. |
* @param s2 Start address of the second interval. |
* @param sz2 Size of the second interval. |
*/ |
static inline int overlaps(uintptr_t s1, size_t sz1, uintptr_t s2, size_t sz2) |
62,35 → 59,19 |
{ |
uintptr_t e1 = s1 + sz1; |
uintptr_t e2 = s2 + sz2; |
return ((s1 < e2) && (s2 < e1)); |
return (s1 < e2) && (s2 < e1); |
} |
/* Compute overlapping of physical addresses */ |
#define PA_overlaps(x, szx, y, szy) \ |
overlaps(KA2PA((x)), (szx), KA2PA((y)), (szy)) |
#define PA_overlaps(x, szx, y, szy) overlaps(KA2PA(x), szx, KA2PA(y), szy) |
#define SIZE2KB(size) ((size) >> 10) |
#define SIZE2MB(size) ((size) >> 20) |
#define SIZE2KB(size) (size >> 10) |
#define SIZE2MB(size) (size >> 20) |
#define KB2SIZE(kb) ((kb) << 10) |
#define MB2SIZE(mb) ((mb) << 20) |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
#define STRING(arg) STRING_ARG(arg) |
#define STRING_ARG(arg) #arg |
/** Pseudorandom generator |
* |
* A pretty standard linear congruential pseudorandom |
* number generator (m = 2^32 or 2^64 depending on architecture). |
* |
*/ |
#define RANDI(seed) \ |
({ \ |
(seed) = 1103515245 * (seed) + 12345; \ |
(seed); \ |
}) |
#endif |
/** @} |
/branches/dd/kernel/generic/include/errno.h |
---|
48,18 → 48,14 |
* sys_ipc_hangup() to close the connection. |
* Used by answerbox to close the connection. |
*/ |
#define EPARTY -8 /* The other party encountered an error when |
* receiving the call. |
*/ |
#define EEXISTS -9 /* Entry already exists */ |
#define EBADMEM -10 /* Bad memory pointer */ |
#define ENOTSUP -11 /* Not supported */ |
#define EADDRNOTAVAIL -12 /* Address not available. */ |
#define ETIMEOUT -13 /* Timeout expired */ |
#define EINVAL -14 /* Invalid value */ |
#define EBUSY -15 /* Resource is busy */ |
#define EOVERFLOW -16 /* The result does not fit its size. */ |
#define EINTR -17 /* Operation was interrupted. */ |
#define EEXISTS -8 /* Entry already exists */ |
#define EBADMEM -9 /* Bad memory pointer */ |
#define ENOTSUP -10 /* Not supported */ |
#define EADDRNOTAVAIL -11 /* Address not available. */ |
#define ETIMEOUT -12 /* Timeout expired */ |
#define EINVAL -13 /* Invalid value */ |
#define EBUSY -14 /* Resource is busy */ |
#define EOVERFLOW -15 /* The result does not fit its size. */ |
#endif |
/branches/dd/kernel/generic/include/panic.h |
---|
36,15 → 36,15 |
#define KERN_PANIC_H_ |
#ifdef CONFIG_DEBUG |
# define panic(format, ...) \ |
panic_printf("Kernel panic in %s() at %s:%u: " format "\n", \ |
__func__, __FILE__, __LINE__, ##__VA_ARGS__); |
#define panic(format, ...) \ |
panic_printf("Kernel panic in %s() at %s on line %d: " format, __func__, \ |
__FILE__, __LINE__, ##__VA_ARGS__); |
#else |
# define panic(format, ...) \ |
panic_printf("Kernel panic: " format "\n", ##__VA_ARGS__); |
#define panic(format, ...) \ |
panic_printf("Kernel panic: " format, ##__VA_ARGS__); |
#endif |
extern void panic_printf(char *fmt, ...) __attribute__((noreturn)); |
extern void panic_printf(char *fmt, ...) __attribute__((noreturn)) ; |
#endif |
/branches/dd/kernel/generic/include/syscall/syscall.h |
---|
36,26 → 36,17 |
#define KERN_SYSCALL_H_ |
typedef enum { |
SYS_KLOG = 0, |
SYS_IO = 0, |
SYS_TLS_SET = 1, /* Hardcoded in AMD64, IA32 uspace - fibril.S */ |
SYS_THREAD_CREATE, |
SYS_THREAD_EXIT, |
SYS_THREAD_GET_ID, |
SYS_TASK_GET_ID, |
SYS_TASK_SET_NAME, |
SYS_PROGRAM_SPAWN_LOADER, |
SYS_FUTEX_SLEEP, |
SYS_FUTEX_WAKEUP, |
SYS_SMC_COHERENCE, |
SYS_AS_AREA_CREATE, |
SYS_AS_AREA_RESIZE, |
SYS_AS_AREA_CHANGE_FLAGS, |
SYS_AS_AREA_DESTROY, |
SYS_IPC_CALL_SYNC_FAST, |
SYS_IPC_CALL_SYNC_SLOW, |
SYS_IPC_CALL_ASYNC_FAST, |
63,25 → 54,18 |
SYS_IPC_ANSWER_FAST, |
SYS_IPC_ANSWER_SLOW, |
SYS_IPC_FORWARD_FAST, |
SYS_IPC_FORWARD_SLOW, |
SYS_IPC_WAIT, |
SYS_IPC_HANGUP, |
SYS_IPC_REGISTER_IRQ, |
SYS_IPC_UNREGISTER_IRQ, |
SYS_CAP_GRANT, |
SYS_CAP_REVOKE, |
SYS_PHYSMEM_MAP, |
SYS_IOSPACE_ENABLE, |
SYS_PREEMPT_CONTROL, |
SYS_SYSINFO_VALID, |
SYS_SYSINFO_VALUE, |
SYS_DEBUG_ENABLE_CONSOLE, |
SYS_DEBUG_DISABLE_CONSOLE, |
SYS_IPC_CONNECT_KBOX, |
SYSCALL_END |
} syscall_t; |
/branches/dd/kernel/generic/include/adt/avl.h |
---|
36,7 → 36,6 |
#define KERN_AVLTREE_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
/** |
* Macro for getting a pointer to the structure which contains the avltree |
/branches/dd/kernel/generic/include/adt/list.h |
---|
36,7 → 36,6 |
#define KERN_LIST_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
/** Doubly linked list head and link type. */ |
typedef struct link { |
/branches/dd/kernel/generic/include/adt/bitmap.h |
---|
49,14 → 49,6 |
extern void bitmap_clear_range(bitmap_t *bitmap, index_t start, count_t bits); |
extern void bitmap_copy(bitmap_t *dst, bitmap_t *src, count_t bits); |
static inline int bitmap_get(bitmap_t *bitmap,index_t bit) |
{ |
if(bit >= bitmap->bits) |
return 0; |
return !! ((bitmap->map)[bit/8] & (1 << (bit & 7))); |
} |
#endif |
/** @} |
/branches/dd/kernel/generic/include/synch/smc.h |
---|
File deleted |
/branches/dd/kernel/generic/include/synch/spinlock.h |
---|
36,7 → 36,6 |
#define KERN_SPINLOCK_H_ |
#include <arch/types.h> |
#include <arch/barrier.h> |
#include <preemption.h> |
#include <atomic.h> |
#include <debug.h> |
111,8 → 110,8 |
#define DEADLOCK_PROBE(pname, value) \ |
if ((pname)++ > (value)) { \ |
(pname) = 0; \ |
printf("Deadlock probe %s: exceeded threshold %u\n", \ |
"cpu%u: function=%s, line=%u\n", \ |
printf("Deadlock probe %s: exceeded threshold %d\n", \ |
"cpu%d: function=%s, line=%d\n", \ |
#pname, (value), CPU->id, __func__, __LINE__); \ |
} |
#else |
/branches/dd/kernel/generic/include/synch/mutex.h |
---|
39,26 → 39,20 |
#include <synch/semaphore.h> |
#include <synch/synch.h> |
typedef enum { |
MUTEX_PASSIVE, |
MUTEX_ACTIVE |
} mutex_type_t; |
typedef struct { |
mutex_type_t type; |
semaphore_t sem; |
} mutex_t; |
#define mutex_lock(mtx) \ |
#define mutex_lock(mtx) \ |
_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE) |
#define mutex_trylock(mtx) \ |
#define mutex_trylock(mtx) \ |
_mutex_lock_timeout((mtx), SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NON_BLOCKING) |
#define mutex_lock_timeout(mtx, usec) \ |
#define mutex_lock_timeout(mtx, usec) \ |
_mutex_lock_timeout((mtx), (usec), SYNCH_FLAGS_NON_BLOCKING) |
extern void mutex_initialize(mutex_t *, mutex_type_t); |
extern int _mutex_lock_timeout(mutex_t *, uint32_t, int); |
extern void mutex_unlock(mutex_t *); |
extern void mutex_initialize(mutex_t *mtx); |
extern int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags); |
extern void mutex_unlock(mutex_t *mtx); |
#endif |
/branches/dd/kernel/generic/include/interrupt.h |
---|
40,16 → 40,17 |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <console/klog.h> |
#include <ddi/irq.h> |
typedef void (* iroutine)(int n, istate_t *istate); |
#define fault_if_from_uspace(istate, fmt, ...) \ |
#define fault_if_from_uspace(istate, cmd, ...) \ |
{ \ |
if (istate_from_uspace(istate)) { \ |
task_t *task = TASK; \ |
printf("Task %s (%" PRIu64 ") killed due to an exception at %p: ", task->name, task->taskid, istate_get_pc(istate)); \ |
printf(fmt "\n", ##__VA_ARGS__); \ |
klog_printf("Task %llu killed due to an exception at %p.", task->taskid, istate_get_pc(istate)); \ |
klog_printf(" " cmd, ##__VA_ARGS__); \ |
task_kill(task->taskid); \ |
thread_exit(); \ |
} \ |
/branches/dd/kernel/generic/include/arch.h |
---|
63,11 → 63,12 |
as_t *as; /**< Current address space. */ |
} the_t; |
#define THE ((the_t * )(get_stack_base())) |
#define THE ((the_t *)(get_stack_base())) |
extern void the_initialize(the_t *the); |
extern void the_copy(the_t *src, the_t *dst); |
extern void arch_pre_main(void); |
extern void arch_pre_mm_init(void); |
extern void arch_post_mm_init(void); |
extern void arch_post_cpu_init(void); |
78,7 → 79,6 |
extern void reboot(void); |
extern void arch_reboot(void); |
extern void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller); |
#endif |
/branches/dd/kernel/generic/include/ddi/irq.h |
---|
36,16 → 36,18 |
#define KERN_IRQ_H_ |
typedef enum { |
CMD_PIO_READ_8 = 1, |
CMD_PIO_READ_16, |
CMD_PIO_READ_32, |
CMD_PIO_WRITE_8, |
CMD_PIO_WRITE_16, |
CMD_PIO_WRITE_32, |
CMD_BTEST, |
CMD_PREDICATE, |
CMD_ACCEPT, |
CMD_DECLINE, |
CMD_MEM_READ_1 = 0, |
CMD_MEM_READ_2, |
CMD_MEM_READ_4, |
CMD_MEM_READ_8, |
CMD_MEM_WRITE_1, |
CMD_MEM_WRITE_2, |
CMD_MEM_WRITE_4, |
CMD_MEM_WRITE_8, |
CMD_PORT_READ_1, |
CMD_PORT_WRITE_1, |
CMD_IA64_GETCHAR, |
CMD_PPC32_GETCHAR, |
CMD_LAST |
} irq_cmd_type; |
52,9 → 54,8 |
typedef struct { |
irq_cmd_type cmd; |
void *addr; |
unsigned long long value; |
unsigned int srcarg; |
unsigned int dstarg; |
unsigned long long value; |
int dstarg; |
} irq_cmd_t; |
typedef struct { |
66,10 → 67,8 |
#include <arch/types.h> |
#include <adt/list.h> |
#include <adt/hash_table.h> |
#include <synch/spinlock.h> |
#include <proc/task.h> |
#include <ipc/ipc.h> |
typedef enum { |
IRQ_DECLINE, /**< Decline to service. */ |
82,11 → 81,8 |
} irq_trigger_t; |
struct irq; |
typedef void (* irq_handler_t)(struct irq *); |
typedef void (* irq_handler_t)(struct irq *irq, void *arg, ...); |
/** Type for function used to clear the interrupt. */ |
typedef void (* cir_t)(void *, inr_t); |
/** IPC notification config structure. |
* |
* Primarily, this structure is encapsulated in the irq_t structure. |
99,8 → 95,6 |
answerbox_t *answerbox; |
/** Method to be used for the notification. */ |
unative_t method; |
/** Arguments that will be sent if the IRQ is claimed. */ |
unative_t scratch[IPC_CALL_LEN]; |
/** Top-half pseudocode. */ |
irq_code_t *code; |
/** Counter. */ |
144,29 → 138,22 |
/** Trigger level of the IRQ. */ |
irq_trigger_t trigger; |
/** Claim ownership of the IRQ. */ |
irq_ownership_t (* claim)(struct irq *); |
irq_ownership_t (* claim)(void); |
/** Handler for this IRQ and device. */ |
irq_handler_t handler; |
/** Instance argument for the handler and the claim function. */ |
void *instance; |
/** Argument for the handler. */ |
void *arg; |
/** Clear interrupt routine. */ |
cir_t cir; |
/** First argument to the clear interrupt routine. */ |
void *cir_arg; |
/** Notification configuration structure. */ |
ipc_notif_cfg_t notif_cfg; |
} irq_t; |
SPINLOCK_EXTERN(irq_uspace_hash_table_lock); |
extern hash_table_t irq_uspace_hash_table; |
extern void irq_init(count_t inrs, count_t chains); |
extern void irq_initialize(irq_t *irq); |
extern void irq_register(irq_t *irq); |
extern irq_t *irq_dispatch_and_lock(inr_t inr); |
extern irq_t *irq_find_and_lock(inr_t inr, devno_t devno); |
extern void irq_init(count_t, count_t); |
extern void irq_initialize(irq_t *); |
extern void irq_register(irq_t *); |
extern irq_t *irq_dispatch_and_lock(inr_t); |
#endif |
#endif |
/branches/dd/kernel/generic/include/ddi/device.h |
---|
35,9 → 35,6 |
#ifndef KERN_DEVICE_H_ |
#define KERN_DEVICE_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
extern devno_t device_assign_devno(void); |
#endif |
/branches/dd/kernel/generic/include/ddi/ddi.h |
---|
38,14 → 38,13 |
#include <ddi/ddi_arg.h> |
#include <arch/types.h> |
#include <proc/task.h> |
#include <adt/list.h> |
/** Structure representing contiguous physical memory area. */ |
typedef struct { |
uintptr_t pbase; /**< Physical base of the area. */ |
pfn_t frames; /**< Number of frames in the area. */ |
link_t link; /**< Linked list link */ |
uintptr_t pbase; /**< Physical base of the area. */ |
uintptr_t vbase; /**< Virtual base of the area. */ |
count_t frames; /**< Number of frames in the area. */ |
bool cacheable; /**< Cacheability. */ |
} parea_t; |
extern void ddi_init(void); |
/branches/dd/kernel/generic/include/memstr.h |
---|
42,9 → 42,9 |
* Architecture independent variants. |
*/ |
extern void *_memcpy(void *dst, const void *src, size_t cnt); |
extern void _memsetb(void *dst, size_t cnt, uint8_t x); |
extern void _memsetw(void *dst, size_t cnt, uint16_t x); |
extern void *memmove(void *dst, const void *src, size_t cnt); |
extern void _memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern void _memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern char *strcpy(char *dest, const char *src); |
#endif |
/branches/dd/kernel/generic/include/console/chardev.h |
---|
50,7 → 50,7 |
/** Resume pushing characters. */ |
void (* resume)(struct chardev *); |
/** Write character to stream. */ |
void (* write)(struct chardev *, char c, bool silent); |
void (* write)(struct chardev *, char c); |
/** Read character directly from device, assume interrupts disabled. */ |
char (* read)(struct chardev *); |
} chardev_operations_t; |
/branches/dd/kernel/generic/include/console/kconsole.h |
---|
37,7 → 37,6 |
#include <adt/list.h> |
#include <synch/spinlock.h> |
#include <ipc/irq.h> |
#define MAX_CMDLINE 256 |
#define KCONSOLE_HISTORY 10 |
84,16 → 83,11 |
void (* help)(void); |
} cmd_info_t; |
extern bool kconsole_notify; |
extern irq_t kconsole_irq; |
SPINLOCK_EXTERN(cmd_lock); |
extern link_t cmd_head; |
extern void kconsole_init(void); |
extern void kconsole_notify_init(void); |
extern void kconsole(char *prompt, char *msg, bool kcon); |
extern void kconsole_thread(void *data); |
extern void kconsole(void *prompt); |
extern int cmd_register(cmd_info_t *cmd); |
/branches/dd/kernel/generic/include/console/console.h |
---|
41,21 → 41,11 |
extern chardev_t *stdin; |
extern chardev_t *stdout; |
extern bool silent; |
extern void console_init(void); |
extern void klog_init(void); |
extern void klog_update(void); |
extern uint8_t getc(chardev_t *chardev); |
extern uint8_t _getc(chardev_t *chardev); |
uint8_t _getc(chardev_t *chardev); |
extern count_t gets(chardev_t *chardev, char *buf, size_t buflen); |
extern void putchar(char c); |
extern void grab_console(void); |
extern void release_console(void); |
extern void arch_grab_console(void); |
extern void arch_release_console(void); |
/branches/dd/kernel/generic/include/console/klog.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genericklog |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_KLOG_H_ |
#define KERN_KLOG_H_ |
void klog_init(void); |
void klog_printf(const char *fmt, ...); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/generic/include/func.h |
---|
41,6 → 41,11 |
extern atomic_t haltstate; |
extern void halt(void); |
extern size_t strlen(const char *str); |
extern int strcmp(const char *src, const char *dst); |
extern int strncmp(const char *src, const char *dst, size_t len); |
extern void strncpy(char *dest, const char *src, size_t len); |
extern unative_t atoi(const char *text); |
extern void order(const uint64_t val, uint64_t *rv, char *suffix); |
/branches/dd/kernel/generic/include/fpu_context.h |
---|
37,6 → 37,10 |
#include <arch/fpu_context.h> |
#if defined(CONFIG_FPU_LAZY) && !defined(ARCH_HAS_FPU) |
# error "CONFIG_FPU_LAZY defined, but no ARCH_HAS_FPU" |
#endif |
extern void fpu_context_save(fpu_context_t *); |
extern void fpu_context_restore(fpu_context_t *); |
extern void fpu_init(void); |
/branches/dd/kernel/generic/include/debug.h |
---|
38,11 → 38,11 |
#include <panic.h> |
#include <arch/debug.h> |
#define CALLER ((uintptr_t) __builtin_return_address(0)) |
#define CALLER ((uintptr_t)__builtin_return_address(0)) |
#ifndef HERE |
/** Current Instruction Pointer address */ |
# define HERE ((uintptr_t *) 0) |
# define HERE ((uintptr_t *) 0) |
#endif |
/** Debugging ASSERT macro |
55,51 → 55,12 |
* |
*/ |
#ifdef CONFIG_DEBUG |
# define ASSERT(expr) \ |
if (!(expr)) { \ |
panic("Assertion failed (%s), caller=%p.", #expr, CALLER); \ |
} |
# define ASSERT(expr) if (!(expr)) { panic("assertion failed (%s), caller=%.*p\n", #expr, sizeof(uintptr_t) * 2, CALLER); } |
#else |
# define ASSERT(expr) |
#endif |
/** Extensive logging output macro |
* |
* If CONFIG_LOG is set, the LOG() macro |
* will print whatever message is indicated plus |
* an information about the location. |
* |
*/ |
#ifdef CONFIG_LOG |
# define LOG(format, ...) \ |
printf("%s() at %s:%u: " format "\n", __func__, __FILE__, \ |
__LINE__, ##__VA_ARGS__); |
#else |
# define LOG(format, ...) |
#endif |
/** Extensive logging execute macro |
* |
* If CONFIG_LOG is set, the LOG_EXEC() macro |
* will print an information about calling a given |
* function and call it. |
* |
*/ |
#ifdef CONFIG_LOG |
# define LOG_EXEC(fnc) \ |
{ \ |
printf("%s() at %s:%u: " #fnc "\n", __func__, __FILE__, \ |
__LINE__); \ |
fnc; \ |
} |
#else |
# define LOG_EXEC(fnc) fnc |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/kernel/generic/include/main/main.h |
---|
35,13 → 35,8 |
#ifndef KERN_MAIN_H_ |
#define KERN_MAIN_H_ |
#include <arch/types.h> |
extern uintptr_t stack_safe; |
extern void main_bsp(void); |
extern void main_ap(void); |
#endif |
/** @} |
/branches/dd/kernel/generic/include/typedefs.h |
---|
35,26 → 35,8 |
#ifndef KERN_TYPEDEFS_H_ |
#define KERN_TYPEDEFS_H_ |
#include <arch/types.h> |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef void (* function)(); |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
#endif |
/** @} |
/branches/dd/kernel/generic/include/align.h |
---|
26,13 → 26,13 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup generic |
* @ingroup others |
* @{ |
*/ |
/** |
* @file |
* @brief Macros for making values and addresses aligned. |
* @brief Macros for making values and addresses aligned. |
*/ |
#ifndef KERN_ALIGN_H_ |
43,7 → 43,7 |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
/** Align to the nearest higher address. |
51,7 → 51,7 |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) |
#define ALIGN_UP(s, a) (((s) + ((a) - 1)) & ~((a) - 1)) |
#endif |
/branches/dd/kernel/generic/include/stackarg.h |
---|
52,9 → 52,9 |
(ap).last = (uint8_t *) &(lst) |
#define va_arg(ap, type) \ |
(*((type *)((ap).last + ((ap).pos += sizeof(type)) - sizeof(type)))) |
(*((type *)((ap).last + ((ap).pos += sizeof(type) ) - sizeof(type)))) |
#define va_copy(dst, src) dst = src |
#define va_copy(dst,src) dst=src |
#define va_end(ap) |
/branches/dd/kernel/generic/include/stdarg.h |
---|
45,7 → 45,7 |
#define va_start(ap, last) __builtin_va_start(ap, last) |
#define va_arg(ap, type) __builtin_va_arg(ap, type) |
#define va_end(ap) __builtin_va_end(ap) |
#define va_copy(dst, src) __builtin_va_copy(dst, src) |
#define va_copy(dst,src) __builtin_va_copy(dst,src) |
#endif |
/branches/dd/kernel/generic/src/udebug/udebug_ops.c |
---|
File deleted |
/branches/dd/kernel/generic/src/udebug/udebug_ipc.c |
---|
File deleted |
/branches/dd/kernel/generic/src/udebug/udebug.c |
---|
File deleted |
/branches/dd/kernel/generic/src/ipc/kbox.c |
---|
File deleted |
/branches/dd/kernel/generic/src/ipc/sysipc.c |
---|
42,9 → 42,8 |
#include <ipc/sysipc.h> |
#include <ipc/irq.h> |
#include <ipc/ipcrsc.h> |
#include <ipc/kbox.h> |
#include <udebug/udebug_ipc.h> |
#include <arch/interrupt.h> |
#include <print.h> |
#include <syscall/copy.h> |
#include <security/cap.h> |
#include <mm/as.h> |
271,12 → 270,12 |
/* The recipient agreed to receive data. */ |
int rc; |
uintptr_t dst; |
size_t size; |
size_t max_size; |
uintptr_t size; |
uintptr_t max_size; |
dst = (uintptr_t)IPC_GET_ARG1(answer->data); |
size = (size_t)IPC_GET_ARG2(answer->data); |
max_size = (size_t)IPC_GET_ARG2(*olddata); |
dst = IPC_GET_ARG1(answer->data); |
size = IPC_GET_ARG2(answer->data); |
max_size = IPC_GET_ARG2(*olddata); |
if (size <= max_size) { |
rc = copy_to_uspace((void *) dst, |
296,11 → 295,10 |
/** Called before the request is sent. |
* |
* @param call Call structure with the request. |
* @param phone Phone that the call will be sent through. |
* |
* @return Return 0 on success, ELIMIT or EPERM on error. |
*/ |
static int request_preprocess(call_t *call, phone_t *phone) |
static int request_preprocess(call_t *call) |
{ |
int newphid; |
size_t size; |
342,10 → 340,6 |
return rc; |
} |
break; |
#ifdef CONFIG_UDEBUG |
case IPC_M_DEBUG_ALL: |
return udebug_request_preprocess(call, phone); |
#endif |
default: |
break; |
} |
375,7 → 369,6 |
if (call->buffer) { |
/* This must be an affirmative answer to IPC_M_DATA_READ. */ |
/* or IPC_M_DEBUG_ALL/UDEBUG_M_MEM_READ... */ |
uintptr_t dst = IPC_GET_ARG1(call->data); |
size_t size = IPC_GET_ARG2(call->data); |
int rc = copy_to_uspace((void *) dst, call->buffer, size); |
406,13 → 399,7 |
return -1; |
} |
IPC_SET_ARG5(call->data, phoneid); |
} |
switch (IPC_GET_METHOD(call->data)) { |
case IPC_M_DEBUG_ALL: |
return -1; |
default: |
break; |
} |
} |
return 0; |
} |
439,7 → 426,7 |
phone_t *phone; |
int res; |
int rc; |
GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
ipc_call_static_init(&call); |
454,18 → 441,9 |
IPC_SET_ARG4(call.data, 0); |
IPC_SET_ARG5(call.data, 0); |
if (!(res = request_preprocess(&call, phone))) { |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = ipc_call_sync(phone, &call); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (rc != EOK) |
return rc; |
if (!(res = request_preprocess(&call))) { |
ipc_call_sync(phone, &call); |
process_answer(&call); |
} else { |
IPC_SET_RETVAL(call.data, res); |
} |
501,16 → 479,8 |
GET_CHECK_PHONE(phone, phoneid, return ENOENT); |
if (!(res = request_preprocess(&call, phone))) { |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = ipc_call_sync(phone, &call); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (rc != EOK) |
return rc; |
if (!(res = request_preprocess(&call))) { |
ipc_call_sync(phone, &call); |
process_answer(&call); |
} else |
IPC_SET_RETVAL(call.data, res); |
576,7 → 546,7 |
*/ |
IPC_SET_ARG5(call->data, 0); |
if (!(res = request_preprocess(call, phone))) |
if (!(res = request_preprocess(call))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
610,7 → 580,7 |
ipc_call_free(call); |
return (unative_t) rc; |
} |
if (!(res = request_preprocess(call, phone))) |
if (!(res = request_preprocess(call))) |
ipc_call(phone, call); |
else |
ipc_backsend_err(phone, call, res); |
618,8 → 588,7 |
return (unative_t) call; |
} |
/** Forward a received call to another destination - common code for both the |
* fast and the slow version. |
/** Forward a received call to another destination. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
626,21 → 595,23 |
* @param method New method to use for the forwarded call. |
* @param arg1 New value of the first argument for the forwarded call. |
* @param arg2 New value of the second argument for the forwarded call. |
* @param arg3 New value of the third argument for the forwarded call. |
* @param arg4 New value of the fourth argument for the forwarded call. |
* @param arg5 New value of the fifth argument for the forwarded call. |
* @param mode Flags that specify mode of the forward operation. |
* @param slow If true, arg3, arg4 and arg5 are considered. Otherwise |
* the function considers only the fast version arguments: |
* i.e. arg1 and arg2. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* Warning: Make sure that ARG5 is not rewritten for certain system IPC |
* In case the original method is a system method, ARG1, ARG2 and ARG3 are |
* overwritten in the forwarded message with the new method and the new arg1 and |
* arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are rewritten with |
* the new method, arg1 and arg2, respectively. Also note there is a set of |
* immutable methods, for which the new method and argument is not set and |
* these values are ignored. |
* |
* Warning: When implementing support for changing additional payload |
* arguments, make sure that ARG5 is not rewritten for certain |
* system IPC |
*/ |
static unative_t sys_ipc_forward_common(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, unative_t arg3, |
unative_t arg4, unative_t arg5, int mode, bool slow) |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode) |
{ |
call_t *call; |
phone_t *phone; |
648,7 → 619,7 |
call = get_call(callid); |
if (!call) |
return ENOENT; |
call->flags |= IPC_CALL_FORWARDED; |
GET_CHECK_PHONE(phone, phoneid, { |
655,7 → 626,7 |
IPC_SET_RETVAL(call->data, EFORWARD); |
ipc_answer(&TASK->answerbox, call); |
return ENOENT; |
}); |
}); |
if (!method_is_forwardable(IPC_GET_METHOD(call->data))) { |
IPC_SET_RETVAL(call->data, EFORWARD); |
665,8 → 636,8 |
/* |
* Userspace is not allowed to change method of system methods on |
* forward, allow changing ARG1, ARG2, ARG3 and ARG4 by means of method, |
* arg1, arg2 and arg3. |
* forward, allow changing ARG1, ARG2 and ARG3 by means of method, |
* arg1 and arg2. |
* If the method is immutable, don't change anything. |
*/ |
if (!method_is_immutable(IPC_GET_METHOD(call->data))) { |
677,22 → 648,10 |
IPC_SET_ARG1(call->data, method); |
IPC_SET_ARG2(call->data, arg1); |
IPC_SET_ARG3(call->data, arg2); |
if (slow) { |
IPC_SET_ARG4(call->data, arg3); |
/* |
* For system methods we deliberately don't |
* overwrite ARG5. |
*/ |
} |
} else { |
IPC_SET_METHOD(call->data, method); |
IPC_SET_ARG1(call->data, arg1); |
IPC_SET_ARG2(call->data, arg2); |
if (slow) { |
IPC_SET_ARG3(call->data, arg3); |
IPC_SET_ARG4(call->data, arg4); |
IPC_SET_ARG5(call->data, arg5); |
} |
} |
} |
699,64 → 658,6 |
return ipc_forward(call, phone, &TASK->answerbox, mode); |
} |
/** Forward a received call to another destination - fast version. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
* @param method New method to use for the forwarded call. |
* @param arg1 New value of the first argument for the forwarded call. |
* @param arg2 New value of the second argument for the forwarded call. |
* @param mode Flags that specify mode of the forward operation. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* In case the original method is a system method, ARG1, ARG2 and ARG3 are |
* overwritten in the forwarded message with the new method and the new |
* arg1 and arg2, respectively. Otherwise the METHOD, ARG1 and ARG2 are |
* rewritten with the new method, arg1 and arg2, respectively. Also note there |
* is a set of immutable methods, for which the new method and arguments are not |
* set and these values are ignored. |
*/ |
unative_t sys_ipc_forward_fast(unative_t callid, unative_t phoneid, |
unative_t method, unative_t arg1, unative_t arg2, int mode) |
{ |
return sys_ipc_forward_common(callid, phoneid, method, arg1, arg2, 0, 0, |
0, mode, false); |
} |
/** Forward a received call to another destination - slow version. |
* |
* @param callid Hash of the call to forward. |
* @param phoneid Phone handle to use for forwarding. |
* @param data Userspace address of the new IPC data. |
* @param mode Flags that specify mode of the forward operation. |
* |
* @return Return 0 on succes, otherwise return an error code. |
* |
* This function is the slow verision of the sys_ipc_forward_fast interface. |
* It can copy all five new arguments and the new method from the userspace. |
* It naturally extends the functionality of the fast version. For system |
* methods, it additionally stores the new value of arg3 to ARG4. For non-system |
* methods, it additionally stores the new value of arg3, arg4 and arg5, |
* respectively, to ARG3, ARG4 and ARG5, respectively. |
*/ |
unative_t sys_ipc_forward_slow(unative_t callid, unative_t phoneid, |
ipc_data_t *data, int mode) |
{ |
ipc_data_t newdata; |
int rc; |
rc = copy_from_uspace(&newdata.args, &data->args, |
sizeof(newdata.args)); |
if (rc != 0) |
return (unative_t) rc; |
return sys_ipc_forward_common(callid, phoneid, |
IPC_GET_METHOD(newdata), IPC_GET_ARG1(newdata), |
IPC_GET_ARG2(newdata), IPC_GET_ARG3(newdata), |
IPC_GET_ARG4(newdata), IPC_GET_ARG5(newdata), mode, true); |
} |
/** Answer an IPC call - fast version. |
* |
* This function can handle only two return arguments of payload, but is faster |
880,17 → 781,9 |
{ |
call_t *call; |
restart: |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
restart: |
call = ipc_wait_for_call(&TASK->answerbox, usec, |
flags | SYNCH_FLAGS_INTERRUPTIBLE); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
if (!call) |
return 0; |
912,16 → 805,11 |
ASSERT(! (call->flags & IPC_CALL_STATIC_ALLOC)); |
atomic_dec(&TASK->active_calls); |
if (call->flags & IPC_CALL_DISCARD_ANSWER) { |
ipc_call_free(call); |
goto restart; |
} else { |
/* |
* Decrement the counter of active calls only if the |
* call is not an answer to IPC_M_PHONE_HUNGUP, |
* which doesn't contribute to the counter. |
*/ |
atomic_dec(&TASK->active_calls); |
} |
STRUCT_TO_USPACE(&calldata->args, &call->data.args); |
936,21 → 824,6 |
/* Include phone address('id') of the caller in the request, |
* copy whole call->data, not only call->data.args */ |
if (STRUCT_TO_USPACE(calldata, &call->data)) { |
/* |
* The callee will not receive this call and no one else has |
* a chance to answer it. Reply with the EPARTY error code. |
*/ |
ipc_data_t saved_data; |
int saveddata = 0; |
if (answer_need_old(call)) { |
memcpy(&saved_data, &call->data, sizeof(call->data)); |
saveddata = 1; |
} |
IPC_SET_RETVAL(call->data, EPARTY); |
(void) answer_preprocess(call, saveddata ? &saved_data : NULL); |
ipc_answer(&TASK->answerbox, call); |
return 0; |
} |
return (unative_t)call; |
991,30 → 864,5 |
return 0; |
} |
#include <console/console.h> |
/** |
* Syscall connect to a task by id. |
* |
* @return Phone id on success, or negative error code. |
*/ |
unative_t sys_ipc_connect_kbox(sysarg64_t *uspace_taskid_arg) |
{ |
#ifdef CONFIG_UDEBUG |
sysarg64_t taskid_arg; |
int rc; |
rc = copy_from_uspace(&taskid_arg, uspace_taskid_arg, sizeof(sysarg64_t)); |
if (rc != 0) |
return (unative_t) rc; |
LOG("sys_ipc_connect_kbox(%" PRIu64 ")\n", taskid_arg.value); |
return ipc_connect_kbox(taskid_arg.value); |
#else |
return (unative_t) ENOTSUP; |
#endif |
} |
/** @} |
*/ |
/branches/dd/kernel/generic/src/ipc/ipc.c |
---|
43,7 → 43,6 |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <ipc/ipc.h> |
#include <ipc/kbox.h> |
#include <errno.h> |
#include <mm/slab.h> |
#include <arch.h> |
52,7 → 51,6 |
#include <debug.h> |
#include <print.h> |
#include <console/console.h> |
#include <proc/thread.h> |
#include <arch/interrupt.h> |
#include <ipc/irq.h> |
68,7 → 66,7 |
*/ |
static void _ipc_call_init(call_t *call) |
{ |
memsetb(call, sizeof(*call), 0); |
memsetb((uintptr_t) call, sizeof(*call), 0); |
call->callerbox = &TASK->answerbox; |
call->sender = TASK; |
call->buffer = NULL; |
89,8 → 87,7 |
call_t *call; |
call = slab_alloc(ipc_call_slab, flags); |
if (call) |
_ipc_call_init(call); |
_ipc_call_init(call); |
return call; |
} |
163,7 → 160,7 |
*/ |
void ipc_phone_init(phone_t *phone) |
{ |
mutex_initialize(&phone->lock, MUTEX_PASSIVE); |
mutex_initialize(&phone->lock); |
phone->callee = NULL; |
phone->state = IPC_PHONE_FREE; |
atomic_set(&phone->active_calls, 0); |
173,10 → 170,8 |
* |
* @param phone Destination kernel phone structure. |
* @param request Call structure with request. |
* |
* @return EOK on success or EINTR if the sleep was interrupted. |
*/ |
int ipc_call_sync(phone_t *phone, call_t *request) |
void ipc_call_sync(phone_t *phone, call_t *request) |
{ |
answerbox_t sync_box; |
186,10 → 181,7 |
request->callerbox = &sync_box; |
ipc_call(phone, request); |
if (!ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, |
SYNCH_FLAGS_INTERRUPTIBLE)) |
return EINTR; |
return EOK; |
ipc_wait_for_call(&sync_box, SYNCH_NO_TIMEOUT, SYNCH_FLAGS_NONE); |
} |
/** Answer a message which was not dispatched and is not listed in any queue. |
202,13 → 194,6 |
call->flags |= IPC_CALL_ANSWERED; |
if (call->flags & IPC_CALL_FORWARDED) { |
if (call->caller_phone) { |
/* Demasquerade the caller phone. */ |
call->data.phone = call->caller_phone; |
} |
} |
spinlock_lock(&callerbox->lock); |
list_append(&call->link, &callerbox->answers); |
spinlock_unlock(&callerbox->lock); |
361,11 → 346,8 |
list_remove(&call->link); |
spinlock_unlock(&oldbox->lock); |
if (mode & IPC_FF_ROUTE_FROM_ME) { |
if (!call->caller_phone) |
call->caller_phone = call->data.phone; |
if (mode & IPC_FF_ROUTE_FROM_ME) |
call->data.phone = newphone; |
} |
return ipc_call(newphone, call); |
} |
429,7 → 411,7 |
* |
* @param lst Head of the list to be cleaned up. |
*/ |
void ipc_cleanup_call_list(link_t *lst) |
static void ipc_cleanup_call_list(link_t *lst) |
{ |
call_t *call; |
444,31 → 426,33 |
} |
} |
/** Disconnects all phones connected to an answerbox. |
/** Cleans up all IPC communication of the current task. |
* |
* @param box Answerbox to disconnect phones from. |
* @param notify_box If true, the answerbox will get a hangup message for |
* each disconnected phone. |
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you |
* have to change it as well if you want to cleanup other tasks than TASK. |
*/ |
void ipc_answerbox_slam_phones(answerbox_t *box, bool notify_box) |
void ipc_cleanup(void) |
{ |
int i; |
call_t *call; |
phone_t *phone; |
DEADLOCK_PROBE_INIT(p_phonelck); |
ipl_t ipl; |
call_t *call; |
call = notify_box ? ipc_call_alloc(0) : NULL; |
/* Disconnect all our phones ('ipc_phone_hangup') */ |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_hangup(&TASK->phones[i]); |
/* Disconnect all connected irqs */ |
ipc_irq_cleanup(&TASK->answerbox); |
/* Disconnect all phones connected to our answerbox */ |
restart_phones: |
ipl = interrupts_disable(); |
spinlock_lock(&box->lock); |
while (!list_empty(&box->connected_phones)) { |
phone = list_get_instance(box->connected_phones.next, |
spinlock_lock(&TASK->answerbox.lock); |
while (!list_empty(&TASK->answerbox.connected_phones)) { |
phone = list_get_instance(TASK->answerbox.connected_phones.next, |
phone_t, link); |
if (SYNCH_FAILED(mutex_trylock(&phone->lock))) { |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
spinlock_unlock(&TASK->answerbox.lock); |
DEADLOCK_PROBE(p_phonelck, DEADLOCK_THRESHOLD); |
goto restart_phones; |
} |
475,70 → 459,13 |
/* Disconnect phone */ |
ASSERT(phone->state == IPC_PHONE_CONNECTED); |
phone->state = IPC_PHONE_SLAMMED; |
list_remove(&phone->link); |
phone->state = IPC_PHONE_SLAMMED; |
if (notify_box) { |
mutex_unlock(&phone->lock); |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
/* |
* Send one message to the answerbox for each |
* phone. Used to make sure the kbox thread |
* wakes up after the last phone has been |
* disconnected. |
*/ |
IPC_SET_METHOD(call->data, IPC_M_PHONE_HUNGUP); |
call->flags |= IPC_CALL_DISCARD_ANSWER; |
_ipc_call(phone, box, call); |
/* Allocate another call in advance */ |
call = ipc_call_alloc(0); |
/* Must start again */ |
goto restart_phones; |
} |
mutex_unlock(&phone->lock); |
} |
spinlock_unlock(&box->lock); |
interrupts_restore(ipl); |
/* Free unused call */ |
if (call) |
ipc_call_free(call); |
} |
/** Cleans up all IPC communication of the current task. |
* |
* Note: ipc_hangup sets returning answerbox to TASK->answerbox, you |
* have to change it as well if you want to cleanup other tasks than TASK. |
*/ |
void ipc_cleanup(void) |
{ |
int i; |
call_t *call; |
/* Disconnect all our phones ('ipc_phone_hangup') */ |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_hangup(&TASK->phones[i]); |
/* Disconnect all connected irqs */ |
ipc_irq_cleanup(&TASK->answerbox); |
/* Disconnect all phones connected to our regular answerbox */ |
ipc_answerbox_slam_phones(&TASK->answerbox, false); |
#ifdef CONFIG_UDEBUG |
/* Clean up kbox thread and communications */ |
ipc_kbox_cleanup(); |
#endif |
/* Answer all messages in 'calls' and 'dispatched_calls' queues */ |
spinlock_lock(&TASK->answerbox.lock); |
ipc_cleanup_call_list(&TASK->answerbox.dispatched_calls); |
ipc_cleanup_call_list(&TASK->answerbox.calls); |
spinlock_unlock(&TASK->answerbox.lock); |
574,13 → 501,7 |
(call->flags & IPC_CALL_NOTIF)); |
ASSERT(!(call->flags & IPC_CALL_STATIC_ALLOC)); |
/* |
* Record the receipt of this call in the current task's counter |
* of active calls. IPC_M_PHONE_HUNGUP calls do not contribute |
* to this counter so do not record answers to them either. |
*/ |
if (!(call->flags & IPC_CALL_DISCARD_ANSWER)) |
atomic_dec(&TASK->active_calls); |
atomic_dec(&TASK->active_calls); |
ipc_call_free(call); |
} |
} |
641,7 → 562,7 |
default: |
break; |
} |
printf("active: %ld\n", |
printf("active: %d\n", |
atomic_get(&task->phones[i].active_calls)); |
} |
mutex_unlock(&task->phones[i].lock); |
654,10 → 575,8 |
for (tmp = task->answerbox.calls.next; tmp != &task->answerbox.calls; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d " |
"A4:%d A5:%d Flags:%x\n", call, call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
665,14 → 584,12 |
} |
/* Print answerbox - calls */ |
printf("ABOX - DISPATCHED CALLS:\n"); |
for (tmp = task->answerbox.dispatched_calls.next; |
tmp != &task->answerbox.dispatched_calls; |
tmp = tmp->next) { |
for (tmp = task->answerbox.dispatched_calls.next; |
tmp != &task->answerbox.dispatched_calls; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid: %p Srctask:%" PRIu64 " M:%" PRIun |
" A1:%" PRIun " A2:%" PRIun " A3:%" PRIun |
" A4:%" PRIun " A5:%" PRIun " Flags:%x\n", call, |
call->sender->taskid, |
printf("Callid: %p Srctask:%llu M:%d A1:%d A2:%d A3:%d " |
"A4:%d A5:%d Flags:%x\n", call, call->sender->taskid, |
IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
680,12 → 597,10 |
} |
/* Print answerbox - calls */ |
printf("ABOX - ANSWERS:\n"); |
for (tmp = task->answerbox.answers.next; |
tmp != &task->answerbox.answers; |
for (tmp = task->answerbox.answers.next; tmp != &task->answerbox.answers; |
tmp = tmp->next) { |
call = list_get_instance(tmp, call_t, link); |
printf("Callid:%p M:%" PRIun " A1:%" PRIun " A2:%" PRIun |
" A3:%" PRIun " A4:%" PRIun " A5:%" PRIun " Flags:%x\n", |
printf("Callid:%p M:%d A1:%d A2:%d A3:%d A4:%d A5:%d Flags:%x\n", |
call, IPC_GET_METHOD(call->data), IPC_GET_ARG1(call->data), |
IPC_GET_ARG2(call->data), IPC_GET_ARG3(call->data), |
IPC_GET_ARG4(call->data), IPC_GET_ARG5(call->data), |
/branches/dd/kernel/generic/src/ipc/irq.c |
---|
44,28 → 44,8 |
* - ARG1: payload modified by a 'top-half' handler |
* - ARG2: payload modified by a 'top-half' handler |
* - ARG3: payload modified by a 'top-half' handler |
* - ARG4: payload modified by a 'top-half' handler |
* - ARG5: payload modified by a 'top-half' handler |
* - in_phone_hash: interrupt counter (may be needed to assure correct order |
* in multithreaded drivers) |
* |
* Note on synchronization for ipc_irq_register(), ipc_irq_unregister(), |
* ipc_irq_cleanup() and IRQ handlers: |
* |
* By always taking all of the uspace IRQ hash table lock, IRQ structure lock |
* and answerbox lock, we can rule out race conditions between the |
* registration functions and also the cleanup function. Thus the observer can |
* either see the IRQ structure present in both the hash table and the |
* answerbox list or absent in both. Views in which the IRQ structure would be |
* linked in the hash table but not in the answerbox list, or vice versa, are |
* not possible. |
* |
* By always taking the hash table lock and the IRQ structure lock, we can |
* rule out a scenario in which we would free up an IRQ structure, which is |
* still referenced by, for example, an IRQ handler. The locking scheme forces |
* us to lock the IRQ structure only after any progressing IRQs on that |
* structure are finished. Because we hold the hash table lock, we prevent new |
* IRQs from taking new references to the IRQ structure. |
*/ |
#include <arch.h> |
78,8 → 58,78 |
#include <console/console.h> |
#include <print.h> |
/** Free the top-half pseudocode. |
/** Execute code associated with IRQ notification. |
* |
* @param call Notification call. |
* @param code Top-half pseudocode. |
*/ |
static void code_execute(call_t *call, irq_code_t *code) |
{ |
unsigned int i; |
unative_t dstval = 0; |
if (!code) |
return; |
for (i = 0; i < code->cmdcount; i++) { |
switch (code->cmds[i].cmd) { |
case CMD_MEM_READ_1: |
dstval = *((uint8_t *) code->cmds[i].addr); |
break; |
case CMD_MEM_READ_2: |
dstval = *((uint16_t *) code->cmds[i].addr); |
break; |
case CMD_MEM_READ_4: |
dstval = *((uint32_t *) code->cmds[i].addr); |
break; |
case CMD_MEM_READ_8: |
dstval = *((uint64_t *) code->cmds[i].addr); |
break; |
case CMD_MEM_WRITE_1: |
*((uint8_t *) code->cmds[i].addr) = code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_2: |
*((uint16_t *) code->cmds[i].addr) = |
code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_4: |
*((uint32_t *) code->cmds[i].addr) = |
code->cmds[i].value; |
break; |
case CMD_MEM_WRITE_8: |
*((uint64_t *) code->cmds[i].addr) = |
code->cmds[i].value; |
break; |
#if defined(ia32) || defined(amd64) |
case CMD_PORT_READ_1: |
dstval = inb((long) code->cmds[i].addr); |
break; |
case CMD_PORT_WRITE_1: |
outb((long) code->cmds[i].addr, code->cmds[i].value); |
break; |
#endif |
#if defined(ia64) && defined(SKI) |
case CMD_IA64_GETCHAR: |
dstval = _getc(&ski_uconsole); |
break; |
#endif |
#if defined(ppc32) |
case CMD_PPC32_GETCHAR: |
dstval = cuda_get_scancode(); |
break; |
#endif |
default: |
break; |
} |
if (code->cmds[i].dstarg && code->cmds[i].dstarg < |
IPC_CALL_LEN) { |
call->data.args[code->cmds[i].dstarg] = dstval; |
} |
} |
} |
/** Free top-half pseudocode. |
* |
* @param code Pointer to the top-half pseudocode. |
*/ |
static void code_free(irq_code_t *code) |
90,7 → 140,7 |
} |
} |
/** Copy the top-half pseudocode from userspace into the kernel. |
/** Copy top-half pseudocode from userspace into the kernel. |
* |
* @param ucode Userspace address of the top-half pseudocode. |
* |
126,6 → 176,38 |
return code; |
} |
/** Unregister task from IRQ notification. |
* |
* @param box Answerbox associated with the notification. |
* @param inr IRQ number. |
* @param devno Device number. |
*/ |
void ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno) |
{ |
ipl_t ipl; |
irq_t *irq; |
ipl = interrupts_disable(); |
irq = irq_find_and_lock(inr, devno); |
if (irq) { |
if (irq->notif_cfg.answerbox == box) { |
code_free(irq->notif_cfg.code); |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
spinlock_lock(&box->irq_lock); |
list_remove(&irq->notif_cfg.link); |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
} |
} |
interrupts_restore(ipl); |
} |
/** Register an answerbox as a receiving end for IRQ notifications. |
* |
* @param box Receiving answerbox. |
142,10 → 224,6 |
ipl_t ipl; |
irq_code_t *code; |
irq_t *irq; |
unative_t key[] = { |
(unative_t) inr, |
(unative_t) devno |
}; |
if (ucode) { |
code = code_from_uspace(ucode); |
155,15 → 233,21 |
code = NULL; |
} |
/* |
* Allocate and populate the IRQ structure. |
*/ |
irq = malloc(sizeof(irq_t), 0); |
irq_initialize(irq); |
irq->devno = devno; |
irq->inr = inr; |
irq->claim = ipc_irq_top_half_claim; |
irq->handler = ipc_irq_top_half_handler; |
ipl = interrupts_disable(); |
irq = irq_find_and_lock(inr, devno); |
if (!irq) { |
interrupts_restore(ipl); |
code_free(code); |
return ENOENT; |
} |
if (irq->notif_cfg.answerbox) { |
spinlock_unlock(&irq->lock); |
interrupts_restore(ipl); |
code_free(code); |
return EEXISTS; |
} |
irq->notif_cfg.notify = true; |
irq->notif_cfg.answerbox = box; |
irq->notif_cfg.method = method; |
170,140 → 254,14 |
irq->notif_cfg.code = code; |
irq->notif_cfg.counter = 0; |
/* |
* Enlist the IRQ structure in the uspace IRQ hash table and the |
* answerbox's list. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&irq_uspace_hash_table_lock); |
spinlock_lock(&irq->lock); |
spinlock_lock(&box->irq_lock); |
if (hash_table_find(&irq_uspace_hash_table, key)) { |
code_free(code); |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
free(irq); |
interrupts_restore(ipl); |
return EEXISTS; |
} |
hash_table_insert(&irq_uspace_hash_table, key, &irq->link); |
list_append(&irq->notif_cfg.link, &box->irq_head); |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
interrupts_restore(ipl); |
return EOK; |
} |
/** Unregister task from IRQ notification. |
* |
* @param box Answerbox associated with the notification. |
* @param inr IRQ number. |
* @param devno Device number. |
*/ |
int ipc_irq_unregister(answerbox_t *box, inr_t inr, devno_t devno) |
{ |
ipl_t ipl; |
unative_t key[] = { |
(unative_t) inr, |
(unative_t) devno |
}; |
link_t *lnk; |
irq_t *irq; |
ipl = interrupts_disable(); |
spinlock_lock(&irq_uspace_hash_table_lock); |
lnk = hash_table_find(&irq_uspace_hash_table, key); |
if (!lnk) { |
spinlock_unlock(&irq_uspace_hash_table_lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
irq = hash_table_get_instance(lnk, irq_t, link); |
spinlock_lock(&irq->lock); |
spinlock_lock(&box->irq_lock); |
ASSERT(irq->notif_cfg.answerbox == box); |
/* Free up the pseudo code and associated structures. */ |
code_free(irq->notif_cfg.code); |
/* Remove the IRQ from the answerbox's list. */ |
list_remove(&irq->notif_cfg.link); |
/* Remove the IRQ from the uspace IRQ hash table. */ |
hash_table_remove(&irq_uspace_hash_table, key, 2); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&box->irq_lock); |
/* Free up the IRQ structure. */ |
free(irq); |
interrupts_restore(ipl); |
return EOK; |
} |
/** Disconnect all IRQ notifications from an answerbox. |
* |
* This function is effective because the answerbox contains |
* list of all irq_t structures that are registered to |
* send notifications to it. |
* |
* @param box Answerbox for which we want to carry out the cleanup. |
*/ |
void ipc_irq_cleanup(answerbox_t *box) |
{ |
ipl_t ipl; |
loop: |
ipl = interrupts_disable(); |
spinlock_lock(&irq_uspace_hash_table_lock); |
spinlock_lock(&box->irq_lock); |
while (box->irq_head.next != &box->irq_head) { |
link_t *cur = box->irq_head.next; |
irq_t *irq; |
DEADLOCK_PROBE_INIT(p_irqlock); |
unative_t key[2]; |
irq = list_get_instance(cur, irq_t, notif_cfg.link); |
if (!spinlock_trylock(&irq->lock)) { |
/* |
* Avoid deadlock by trying again. |
*/ |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
interrupts_restore(ipl); |
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD); |
goto loop; |
} |
key[0] = irq->inr; |
key[1] = irq->devno; |
ASSERT(irq->notif_cfg.answerbox == box); |
/* Unlist from the answerbox. */ |
list_remove(&irq->notif_cfg.link); |
/* Remove from the hash table. */ |
hash_table_remove(&irq_uspace_hash_table, key, 2); |
/* Free up the pseudo code and associated structures. */ |
code_free(irq->notif_cfg.code); |
spinlock_unlock(&irq->lock); |
free(irq); |
} |
spinlock_unlock(&box->irq_lock); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
interrupts_restore(ipl); |
return 0; |
} |
/** Add a call to the proper answerbox queue. |
322,158 → 280,125 |
waitq_wakeup(&irq->notif_cfg.answerbox->wq, WAKEUP_FIRST); |
} |
/** Apply the top-half pseudo code to find out whether to accept the IRQ or not. |
/** Send notification message. |
* |
* @param irq IRQ structure. |
* |
* @return IRQ_ACCEPT if the interrupt is accepted by the |
* pseudocode. IRQ_DECLINE otherwise. |
* @param a1 Driver-specific payload argument. |
* @param a2 Driver-specific payload argument. |
* @param a3 Driver-specific payload argument. |
* @param a4 Driver-specific payload argument. |
* @param a5 Driver-specific payload argument. |
*/ |
irq_ownership_t ipc_irq_top_half_claim(irq_t *irq) |
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5) |
{ |
unsigned int i; |
unative_t dstval; |
irq_code_t *code = irq->notif_cfg.code; |
unative_t *scratch = irq->notif_cfg.scratch; |
call_t *call; |
if (!irq->notif_cfg.notify) |
return IRQ_DECLINE; |
if (!code) |
return IRQ_DECLINE; |
for (i = 0; i < code->cmdcount; i++) { |
unsigned int srcarg = code->cmds[i].srcarg; |
unsigned int dstarg = code->cmds[i].dstarg; |
spinlock_lock(&irq->lock); |
if (irq->notif_cfg.answerbox) { |
call = ipc_call_alloc(FRAME_ATOMIC); |
if (!call) { |
spinlock_unlock(&irq->lock); |
return; |
} |
call->flags |= IPC_CALL_NOTIF; |
IPC_SET_METHOD(call->data, irq->notif_cfg.method); |
IPC_SET_ARG1(call->data, a1); |
IPC_SET_ARG2(call->data, a2); |
IPC_SET_ARG3(call->data, a3); |
IPC_SET_ARG4(call->data, a4); |
IPC_SET_ARG5(call->data, a5); |
/* Put a counter to the message */ |
call->priv = ++irq->notif_cfg.counter; |
if (srcarg >= IPC_CALL_LEN) |
break; |
if (dstarg >= IPC_CALL_LEN) |
break; |
switch (code->cmds[i].cmd) { |
case CMD_PIO_READ_8: |
dstval = pio_read_8((ioport8_t *) code->cmds[i].addr); |
if (dstarg) |
scratch[dstarg] = dstval; |
break; |
case CMD_PIO_READ_16: |
dstval = pio_read_16((ioport16_t *) code->cmds[i].addr); |
if (dstarg) |
scratch[dstarg] = dstval; |
break; |
case CMD_PIO_READ_32: |
dstval = pio_read_32((ioport32_t *) code->cmds[i].addr); |
if (dstarg) |
scratch[dstarg] = dstval; |
break; |
case CMD_PIO_WRITE_8: |
pio_write_8((ioport8_t *) code->cmds[i].addr, |
(uint8_t) code->cmds[i].value); |
break; |
case CMD_PIO_WRITE_16: |
pio_write_16((ioport16_t *) code->cmds[i].addr, |
(uint16_t) code->cmds[i].value); |
break; |
case CMD_PIO_WRITE_32: |
pio_write_32((ioport32_t *) code->cmds[i].addr, |
(uint32_t) code->cmds[i].value); |
break; |
case CMD_BTEST: |
if (srcarg && dstarg) { |
dstval = scratch[srcarg] & code->cmds[i].value; |
scratch[dstarg] = dstval; |
} |
break; |
case CMD_PREDICATE: |
if (srcarg && !scratch[srcarg]) { |
i += code->cmds[i].value; |
continue; |
} |
break; |
case CMD_ACCEPT: |
return IRQ_ACCEPT; |
break; |
case CMD_DECLINE: |
default: |
return IRQ_DECLINE; |
} |
send_call(irq, call); |
} |
return IRQ_DECLINE; |
spinlock_unlock(&irq->lock); |
} |
/* IRQ top-half handler. |
/** Notify a task that an IRQ had occurred. |
* |
* We expect interrupts to be disabled and the irq->lock already held. |
* |
* @param irq IRQ structure. |
*/ |
void ipc_irq_top_half_handler(irq_t *irq) |
void ipc_irq_send_notif(irq_t *irq) |
{ |
call_t *call; |
ASSERT(irq); |
if (irq->notif_cfg.answerbox) { |
call_t *call; |
call = ipc_call_alloc(FRAME_ATOMIC); |
if (!call) |
if (!call) { |
return; |
} |
call->flags |= IPC_CALL_NOTIF; |
/* Put a counter to the message */ |
call->priv = ++irq->notif_cfg.counter; |
/* Set up args */ |
IPC_SET_METHOD(call->data, irq->notif_cfg.method); |
IPC_SET_ARG1(call->data, irq->notif_cfg.scratch[1]); |
IPC_SET_ARG2(call->data, irq->notif_cfg.scratch[2]); |
IPC_SET_ARG3(call->data, irq->notif_cfg.scratch[3]); |
IPC_SET_ARG4(call->data, irq->notif_cfg.scratch[4]); |
IPC_SET_ARG5(call->data, irq->notif_cfg.scratch[5]); |
/* Execute code to handle irq */ |
code_execute(call, irq->notif_cfg.code); |
send_call(irq, call); |
} |
} |
/** Send notification message. |
/** Disconnect all IRQ notifications from an answerbox. |
* |
* @param irq IRQ structure. |
* @param a1 Driver-specific payload argument. |
* @param a2 Driver-specific payload argument. |
* @param a3 Driver-specific payload argument. |
* @param a4 Driver-specific payload argument. |
* @param a5 Driver-specific payload argument. |
* This function is effective because the answerbox contains |
* list of all irq_t structures that are registered to |
* send notifications to it. |
* |
* @param box Answerbox for which we want to carry out the cleanup. |
*/ |
void ipc_irq_send_msg(irq_t *irq, unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5) |
void ipc_irq_cleanup(answerbox_t *box) |
{ |
call_t *call; |
spinlock_lock(&irq->lock); |
if (irq->notif_cfg.answerbox) { |
call = ipc_call_alloc(FRAME_ATOMIC); |
if (!call) { |
spinlock_unlock(&irq->lock); |
return; |
ipl_t ipl; |
loop: |
ipl = interrupts_disable(); |
spinlock_lock(&box->irq_lock); |
while (box->irq_head.next != &box->irq_head) { |
link_t *cur = box->irq_head.next; |
irq_t *irq; |
DEADLOCK_PROBE_INIT(p_irqlock); |
irq = list_get_instance(cur, irq_t, notif_cfg.link); |
if (!spinlock_trylock(&irq->lock)) { |
/* |
* Avoid deadlock by trying again. |
*/ |
spinlock_unlock(&box->irq_lock); |
interrupts_restore(ipl); |
DEADLOCK_PROBE(p_irqlock, DEADLOCK_THRESHOLD); |
goto loop; |
} |
call->flags |= IPC_CALL_NOTIF; |
/* Put a counter to the message */ |
call->priv = ++irq->notif_cfg.counter; |
ASSERT(irq->notif_cfg.answerbox == box); |
list_remove(&irq->notif_cfg.link); |
/* |
* Don't forget to free any top-half pseudocode. |
*/ |
code_free(irq->notif_cfg.code); |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
IPC_SET_METHOD(call->data, irq->notif_cfg.method); |
IPC_SET_ARG1(call->data, a1); |
IPC_SET_ARG2(call->data, a2); |
IPC_SET_ARG3(call->data, a3); |
IPC_SET_ARG4(call->data, a4); |
IPC_SET_ARG5(call->data, a5); |
send_call(irq, call); |
spinlock_unlock(&irq->lock); |
} |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&box->irq_lock); |
interrupts_restore(ipl); |
} |
/** @} |
/branches/dd/kernel/generic/src/ipc/ipcrsc.c |
---|
170,6 → 170,7 |
int i; |
spinlock_lock(&TASK->lock); |
for (i = 0; i < IPC_MAX_PHONES; i++) { |
if (TASK->phones[i].state == IPC_PHONE_HUNGUP && |
atomic_get(&TASK->phones[i].active_calls) == 0) |
182,9 → 183,8 |
} |
spinlock_unlock(&TASK->lock); |
if (i == IPC_MAX_PHONES) |
if (i >= IPC_MAX_PHONES) |
return -1; |
return i; |
} |
/branches/dd/kernel/generic/src/lib/string.c |
---|
File deleted |
/branches/dd/kernel/generic/src/lib/elf.c |
---|
57,7 → 57,7 |
}; |
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, |
as_t *as, int flags); |
as_t *as); |
static int section_header(elf_section_header_t *entry, elf_header_t *elf, |
as_t *as); |
static int load_segment(elf_segment_header_t *entry, elf_header_t *elf, |
67,10 → 67,9 |
* |
* @param header Pointer to ELF header in memory |
* @param as Created and properly mapped address space |
* @param flags A combination of ELD_F_* |
* @return EE_OK on success |
*/ |
unsigned int elf_load(elf_header_t *header, as_t * as, int flags) |
unsigned int elf_load(elf_header_t *header, as_t * as) |
{ |
int i, rc; |
111,7 → 110,7 |
seghdr = &((elf_segment_header_t *)(((uint8_t *) header) + |
header->e_phoff))[i]; |
rc = segment_header(seghdr, header, as, flags); |
rc = segment_header(seghdr, header, as); |
if (rc != EE_OK) |
return rc; |
} |
152,10 → 151,8 |
* @return EE_OK on success, error code otherwise. |
*/ |
static int segment_header(elf_segment_header_t *entry, elf_header_t *elf, |
as_t *as, int flags) |
as_t *as) |
{ |
char *interp; |
switch (entry->p_type) { |
case PT_NULL: |
case PT_PHDR: |
165,16 → 162,6 |
break; |
case PT_DYNAMIC: |
case PT_INTERP: |
interp = (char *)elf + entry->p_offset; |
/* FIXME */ |
/*if (memcmp((uintptr_t)interp, (uintptr_t)ELF_INTERP_ZSTR, |
ELF_INTERP_ZLEN) != 0) { |
return EE_UNSUPPORTED; |
}*/ |
if ((flags & ELD_F_LOADER) == 0) { |
return EE_LOADER; |
} |
break; |
case PT_SHLIB: |
case PT_NOTE: |
case PT_LOPROC: |
/branches/dd/kernel/generic/src/lib/rd.c |
---|
42,6 → 42,7 |
#include <mm/frame.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
#include <print.h> |
#include <align.h> |
static parea_t rd_parea; /**< Physical memory area for rd. */ |
48,14 → 49,14 |
/** |
* RAM disk initialization routine. At this point, the RAM disk memory is shared |
* and information about the share is provided as sysinfo values to the |
* userspace tasks. |
* and information about the share is provided as sysinfo values to the userspace |
* tasks. |
*/ |
int init_rd(rd_header_t *header, size_t size) |
int init_rd(rd_header * header, size_t size) |
{ |
/* Identify RAM disk */ |
if ((header->magic[0] != RD_MAG0) || (header->magic[1] != RD_MAG1) || |
(header->magic[2] != RD_MAG2) || (header->magic[3] != RD_MAG3)) |
(header->magic[2] != RD_MAG2) || (header->magic[3] != RD_MAG3)) |
return RE_INVALID; |
/* Identify version */ |
79,7 → 80,10 |
if ((hsize % FRAME_SIZE) || (dsize % FRAME_SIZE)) |
return RE_UNSUPPORTED; |
if (dsize % FRAME_SIZE) |
return RE_UNSUPPORTED; |
if (hsize > size) |
return RE_INVALID; |
86,16 → 90,17 |
if ((uint64_t) hsize + dsize > size) |
dsize = size - hsize; |
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize), |
FRAME_SIZE); |
rd_parea.pbase = ALIGN_DOWN((uintptr_t) KA2PA((void *) header + hsize), FRAME_SIZE); |
rd_parea.vbase = (uintptr_t) ((void *) header + hsize); |
rd_parea.frames = SIZE2FRAMES(dsize); |
rd_parea.cacheable = true; |
ddi_parea_register(&rd_parea); |
sysinfo_set_item_val("rd", NULL, true); |
sysinfo_set_item_val("rd.header_size", NULL, hsize); |
sysinfo_set_item_val("rd.size", NULL, dsize); |
sysinfo_set_item_val("rd.address.physical", NULL, |
(unative_t) KA2PA((void *) header + hsize)); |
sysinfo_set_item_val("rd.address.physical", NULL, (unative_t) |
KA2PA((void *) header + hsize)); |
return RE_OK; |
} |
/branches/dd/kernel/generic/src/lib/memstr.c |
---|
1,6 → 1,5 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
35,10 → 34,12 |
* @file |
* @brief Memory string operations. |
* |
* This file provides architecture independent functions to manipulate blocks of |
* memory. These functions are optimized as much as generic functions of this |
* type can be. However, architectures are free to provide even more optimized |
* versions of these functions. |
* This file provides architecture independent functions |
* to manipulate blocks of memory. These functions |
* are optimized as much as generic functions of |
* this type can be. However, architectures are |
* free to provide even more optimized versions of these |
* functions. |
*/ |
#include <memstr.h> |
45,119 → 46,93 |
#include <arch/types.h> |
#include <align.h> |
/** Copy block of memory. |
/** Copy block of memory |
* |
* Copy cnt bytes from src address to dst address. The copying is done |
* word-by-word and then byte-by-byte. The source and destination memory areas |
* cannot overlap. |
* Copy cnt bytes from src address to dst address. |
* The copying is done word-by-word and then byte-by-byte. |
* The source and destination memory areas cannot overlap. |
* |
* @param src Source address to copy from. |
* @param dst Destination address to copy to. |
* @param cnt Number of bytes to copy. |
* @param src Origin address to copy from. |
* @param dst Origin address to copy to. |
* @param cnt Number of bytes to copy. |
* |
* @return Destination address. |
*/ |
void *_memcpy(void *dst, const void *src, size_t cnt) |
void *_memcpy(void * dst, const void *src, size_t cnt) |
{ |
unsigned int i, j; |
if (ALIGN_UP((uintptr_t) src, sizeof(unative_t)) != (uintptr_t) src || |
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) { |
ALIGN_UP((uintptr_t) dst, sizeof(unative_t)) != (uintptr_t) dst) { |
for (i = 0; i < cnt; i++) |
((uint8_t *) dst)[i] = ((uint8_t *) src)[i]; |
} else { |
for (i = 0; i < cnt / sizeof(unative_t); i++) |
for (i = 0; i < cnt/sizeof(unative_t); i++) |
((unative_t *) dst)[i] = ((unative_t *) src)[i]; |
for (j = 0; j < cnt % sizeof(unative_t); j++) |
((uint8_t *)(((unative_t *) dst) + i))[j] = |
((uint8_t *)(((unative_t *) src) + i))[j]; |
for (j = 0; j < cnt%sizeof(unative_t); j++) |
((uint8_t *)(((unative_t *) dst) + i))[j] = ((uint8_t *)(((unative_t *) src) + i))[j]; |
} |
return (char *) dst; |
return (char *) src; |
} |
/** Move memory block with possible overlapping. |
/** Fill block of memory |
* |
* Copy cnt bytes from src address to dst address. The source and destination |
* memory areas may overlap. |
* Fill cnt bytes at dst address with the value x. |
* The filling is done byte-by-byte. |
* |
* @param src Source address to copy from. |
* @param dst Destination address to copy to. |
* @param cnt Number of bytes to copy. |
* @param dst Origin address to fill. |
* @param cnt Number of bytes to fill. |
* @param x Value to fill. |
* |
* @return Destination address. |
*/ |
void *memmove(void *dst, const void *src, size_t n) |
void _memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
const uint8_t *sp; |
uint8_t *dp; |
/* Nothing to do? */ |
if (src == dst) |
return dst; |
/* Non-overlapping? */ |
if (dst >= src + n || src >= dst + n) { |
return memcpy(dst, src, n); |
} |
/* Which direction? */ |
if (src > dst) { |
/* Forwards. */ |
sp = src; |
dp = dst; |
while (n-- != 0) |
*dp++ = *sp++; |
} else { |
/* Backwards. */ |
sp = src + (n - 1); |
dp = dst + (n - 1); |
while (n-- != 0) |
*dp-- = *sp--; |
} |
return dst; |
unsigned int i; |
uint8_t *p = (uint8_t *) dst; |
for (i = 0; i < cnt; i++) |
p[i] = x; |
} |
/** Fill block of memory |
* |
* Fill cnt bytes at dst address with the value x. The filling is done |
* byte-by-byte. |
* Fill cnt words at dst address with the value x. |
* The filling is done word-by-word. |
* |
* @param dst Destination address to fill. |
* @param cnt Number of bytes to fill. |
* @param x Value to fill. |
* @param dst Origin address to fill. |
* @param cnt Number of words to fill. |
* @param x Value to fill. |
* |
*/ |
void _memsetb(void *dst, size_t cnt, uint8_t x) |
void _memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
unsigned int i; |
uint8_t *p = (uint8_t *) dst; |
uint16_t *p = (uint16_t *) dst; |
for (i = 0; i < cnt; i++) |
p[i] = x; |
p[i] = x; |
} |
/** Fill block of memory. |
/** Copy string |
* |
* Fill cnt words at dst address with the value x. The filling is done |
* word-by-word. |
* Copy string from src address to dst address. |
* The copying is done char-by-char until the null |
* character. The source and destination memory areas |
* cannot overlap. |
* |
* @param dst Destination address to fill. |
* @param cnt Number of words to fill. |
* @param x Value to fill. |
* @param src Origin string to copy from. |
* @param dst Origin string to copy to. |
* |
*/ |
void _memsetw(void *dst, size_t cnt, uint16_t x) |
char *strcpy(char *dest, const char *src) |
{ |
unsigned int i; |
uint16_t *p = (uint16_t *) dst; |
char *orig = dest; |
for (i = 0; i < cnt; i++) |
p[i] = x; |
while ((*(dest++) = *(src++))) |
; |
return orig; |
} |
/** @} |
/branches/dd/kernel/generic/src/lib/func.c |
---|
55,6 → 55,8 |
#ifdef CONFIG_DEBUG |
bool rundebugger = false; |
// TODO test_and_set not defined on all arches |
// if (!test_and_set(&haltstate)) |
if (!atomic_get(&haltstate)) { |
atomic_set(&haltstate, 1); |
rundebugger = true; |
64,19 → 66,116 |
#endif |
interrupts_disable(); |
#if (defined(CONFIG_DEBUG)) && (defined(CONFIG_KCONSOLE)) |
if (rundebugger) |
kconsole("panic", "\nLast resort kernel console ready\n", false); |
#endif |
#ifdef CONFIG_DEBUG |
if (rundebugger) { |
printf("\n"); |
kconsole("panic"); /* Run kconsole as a last resort to user */ |
} |
#endif |
if (CPU) |
printf("cpu%u: halted\n", CPU->id); |
printf("cpu%d: halted\n", CPU->id); |
else |
printf("cpu: halted\n"); |
cpu_halt(); |
} |
/** Return number of characters in a string. |
* |
* @param str NULL terminated string. |
* |
* @return Number of characters in str. |
*/ |
size_t strlen(const char *str) |
{ |
int i; |
for (i = 0; str[i]; i++) |
; |
return i; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strcmp(const char *src, const char *dst) |
{ |
for (; *src && *dst; src++, dst++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (*src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths and specified maximal |
* length. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param len Maximal length for comparison. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strncmp(const char *src, const char *dst, size_t len) |
{ |
unsigned int i; |
for (i = 0; (*src) && (*dst) && (i < len); src++, dst++, i++) { |
if (*src < *dst) |
return -1; |
if (*src > *dst) |
return 1; |
} |
if (i == len || *src == *dst) |
return 0; |
if (!*src) |
return -1; |
return 1; |
} |
/** Copy NULL terminated string. |
* |
* Copy at most 'len' characters from string 'src' to 'dest'. |
* If 'src' is shorter than 'len', '\0' is inserted behind the |
* last copied character. |
* |
* @param src Source string. |
* @param dest Destination buffer. |
* @param len Size of destination buffer. |
*/ |
void strncpy(char *dest, const char *src, size_t len) |
{ |
unsigned int i; |
for (i = 0; i < len; i++) { |
if (!(dest[i] = src[i])) |
return; |
} |
dest[i-1] = '\0'; |
} |
/** Convert ascii representation to unative_t |
* |
* Supports 0x for hexa & 0 for octal notation. |
/branches/dd/kernel/generic/src/lib/objc.c |
---|
0,0 → 1,60 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** |
* @file |
* @brief Objective C run-time environment. |
* |
* This file containts the (growing subset of) |
* Objective C run-time environment. The code currently |
* relies on the external libobjc library, but this |
* dependency will be removed eventually. |
*/ |
#include <lib/objc.h> |
@implementation base_t |
+ (id) new |
{ |
return class_create_instance(self); |
} |
- (id) dispose |
{ |
return object_dispose(self); |
} |
@end |
/** @} |
*/ |
/branches/dd/kernel/generic/src/lib/objc_ext.c |
---|
0,0 → 1,174 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
* @{ |
*/ |
/** |
* @file |
* @brief Objective C bindings. |
* |
* This file provides architecture independent binding |
* functions which are needed to link with libobjc run-time |
* library. Many of the functions are just dummy. |
*/ |
#include <lib/objc_ext.h> |
#include <panic.h> |
#include <arch/memstr.h> |
#include <mm/slab.h> |
void *stderr; |
static unsigned short __ctype_b[384] = { |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
2, 2, 2, 2, 2, 2, 2, 2, |
2, 8195, 8194, 8194, 8194, 8194, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, |
24577, 49156, 49156, 49156, 49156, 49156, 49156, 49156, |
49156, 49156, 49156, 49156, 49156, 49156, 49156, 49156, |
55304, 55304, 55304, 55304, 55304, 55304, 55304, 55304, |
55304, 55304, 49156, 49156, 49156, 49156, 49156, 49156, |
49156, 54536, 54536, 54536, 54536, 54536, 54536, 50440, |
50440, 50440, 50440, 50440, 50440, 50440, 50440, 50440, |
50440, 50440, 50440, 50440, 50440, 50440, 50440, 50440, |
50440, 50440, 50440, 49156, 49156, 49156, 49156, 49156, |
49156, 54792, 54792, 54792, 54792, 54792, 54792, 50696, |
50696, 50696, 50696, 50696, 50696, 50696, 50696, 50696, |
50696, 50696, 50696, 50696, 50696, 50696, 50696, 50696, |
50696, 50696, 50696, 49156, 49156, 49156, 49156, 2, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0 |
}; |
static const unsigned short *__ctype_b_ptr = __ctype_b + 128; |
void __assert_fail(const char *assertion, const char *file, unsigned int line, const char *function) |
{ |
panic("Run-time assertion (%s:%d:%s) failed (%s)", file, line, function ? function : "", assertion); |
} |
void abort(void) |
{ |
panic("Run-time scheduled abort"); |
} |
void *fopen(const char *path, const char *mode) |
{ |
return NULL; |
} |
size_t fread(void *ptr, size_t size, size_t nmemb, void *stream) |
{ |
return 0; |
} |
size_t fwrite(const void *ptr, size_t size, size_t nmemb, void *stream) |
{ |
return 0; |
} |
int fflush(void *stream) |
{ |
return 0; |
} |
int feof(void *stream) |
{ |
return 1; |
} |
int fclose(void *stream) |
{ |
return 0; |
} |
int vfprintf(void *stream, const char *format, va_list ap) |
{ |
return 0; |
} |
int sscanf(const char *str, const char *format, ...) |
{ |
return 0; |
} |
const unsigned short **__ctype_b_loc(void) |
{ |
return &__ctype_b_ptr; |
} |
long int __strtol_internal(const char *__nptr, char **__endptr, int __base, int __group) |
{ |
return 0; |
} |
void *memset(void *s, int c, size_t n) |
{ |
memsetb((uintptr_t) s, n, c); |
return s; |
} |
void *calloc(size_t nmemb, size_t size) |
{ |
return malloc(nmemb * size, 0); |
} |
/** @} |
*/ |
/branches/dd/kernel/generic/src/mm/backend_elf.c |
---|
48,7 → 48,6 |
#include <memstr.h> |
#include <macros.h> |
#include <arch.h> |
#include <arch/barrier.h> |
#ifdef CONFIG_VIRT_IDX_DCACHE |
#include <arch/mm/cache.h> |
68,13 → 67,12 |
* |
* The address space area and page tables must be already locked. |
* |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. |
* read/write/exec). |
* @param area Pointer to the address space area. |
* @param addr Faulting virtual address. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK |
* on success (i.e. serviced). |
* @return AS_PF_FAULT on failure (i.e. page fault) or AS_PF_OK on success (i.e. |
* serviced). |
*/ |
int elf_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
118,7 → 116,7 |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == page - area->base) { |
if (leaf->key[i] == page) { |
found = true; |
break; |
} |
129,7 → 127,7 |
page_mapping_insert(AS, addr, frame, |
as_area_get_flags(area)); |
if (!used_space_insert(area, page, 1)) |
panic("Cannot insert used space."); |
panic("Could not insert used space.\n"); |
mutex_unlock(&area->sh_info->lock); |
return AS_PF_OK; |
} |
152,10 → 150,6 |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memcpy((void *) PA2KA(frame), |
(void *) (base + i * FRAME_SIZE), FRAME_SIZE); |
if (entry->p_flags & PF_X) { |
smc_coherence_block((void *) PA2KA(frame), |
FRAME_SIZE); |
} |
dirty = true; |
} else { |
frame = KA2PA(base + i * FRAME_SIZE); |
168,7 → 162,7 |
* and cleared. |
*/ |
frame = (uintptr_t)frame_alloc(ONE_FRAME, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} else { |
size_t pad_lo, pad_hi; |
193,13 → 187,8 |
memcpy((void *) (PA2KA(frame) + pad_lo), |
(void *) (base + i * FRAME_SIZE + pad_lo), |
FRAME_SIZE - pad_lo - pad_hi); |
if (entry->p_flags & PF_X) { |
smc_coherence_block((void *) (PA2KA(frame) + pad_lo), |
FRAME_SIZE - pad_lo - pad_hi); |
} |
memsetb((void *) PA2KA(frame), pad_lo, 0); |
memsetb((void *) (PA2KA(frame) + FRAME_SIZE - pad_hi), pad_hi, |
0); |
memsetb(PA2KA(frame), pad_lo, 0); |
memsetb(PA2KA(frame) + FRAME_SIZE - pad_hi, pad_hi, 0); |
dirty = true; |
} |
214,7 → 203,7 |
page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); |
if (!used_space_insert(area, page, 1)) |
panic("Cannot insert used space."); |
panic("Could not insert used space.\n"); |
return AS_PF_OK; |
} |
223,10 → 212,9 |
* |
* The address space area and page tables must be already locked. |
* |
* @param area Pointer to the address space area. |
* @param page Page that is mapped to frame. Must be aligned to |
* PAGE_SIZE. |
* @param frame Frame to be released. |
* @param area Pointer to the address space area. |
* @param page Page that is mapped to frame. Must be aligned to PAGE_SIZE. |
* @param frame Frame to be released. |
* |
*/ |
void elf_frame_free(as_area_t *area, uintptr_t page, uintptr_t frame) |
269,7 → 257,7 |
* |
* The address space and address space area must be locked prior to the call. |
* |
* @param area Address space area. |
* @param area Address space area. |
*/ |
void elf_share(as_area_t *area) |
{ |
/branches/dd/kernel/generic/src/mm/slab.c |
---|
167,19 → 167,19 |
* Allocate frames for slab space and initialize |
* |
*/ |
static slab_t *slab_space_alloc(slab_cache_t *cache, int flags) |
static slab_t * slab_space_alloc(slab_cache_t *cache, int flags) |
{ |
void *data; |
slab_t *slab; |
size_t fsize; |
unsigned int i; |
count_t zone = 0; |
unsigned int zone = 0; |
data = frame_alloc_generic(cache->order, FRAME_KA | flags, &zone); |
if (!data) { |
return NULL; |
} |
if (!(cache->flags & SLAB_CACHE_SLINSIDE)) { |
if (! (cache->flags & SLAB_CACHE_SLINSIDE)) { |
slab = slab_alloc(slab_extern_cache, flags); |
if (!slab) { |
frame_free(KA2PA(data)); |
200,7 → 200,7 |
slab->cache = cache; |
for (i = 0; i < cache->objects; i++) |
*((int *) (slab->start + i*cache->size)) = i + 1; |
*((int *) (slab->start + i*cache->size)) = i+1; |
atomic_inc(&cache->allocated_slabs); |
return slab; |
239,7 → 239,8 |
* |
* @return Number of freed pages |
*/ |
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, slab_t *slab) |
static count_t slab_obj_destroy(slab_cache_t *cache, void *obj, |
slab_t *slab) |
{ |
int freed = 0; |
255,7 → 256,7 |
ASSERT(slab->available < cache->objects); |
*((int *)obj) = slab->nextavail; |
slab->nextavail = (obj - slab->start) / cache->size; |
slab->nextavail = (obj - slab->start)/cache->size; |
slab->available++; |
/* Move it to correct list */ |
280,7 → 281,7 |
* |
* @return Object address or null |
*/ |
static void *slab_obj_create(slab_cache_t *cache, int flags) |
static void * slab_obj_create(slab_cache_t *cache, int flags) |
{ |
slab_t *slab; |
void *obj; |
300,8 → 301,7 |
return NULL; |
spinlock_lock(&cache->slablock); |
} else { |
slab = list_get_instance(cache->partial_slabs.next, slab_t, |
link); |
slab = list_get_instance(cache->partial_slabs.next, slab_t, link); |
list_remove(&slab->link); |
} |
obj = slab->start + slab->nextavail * cache->size; |
332,7 → 332,8 |
* |
* @param first If true, return first, else last mag |
*/ |
static slab_magazine_t *get_mag_from_cache(slab_cache_t *cache, int first) |
static slab_magazine_t * get_mag_from_cache(slab_cache_t *cache, |
int first) |
{ |
slab_magazine_t *mag = NULL; |
link_t *cur; |
367,7 → 368,8 |
* |
* @return Number of freed pages |
*/ |
static count_t magazine_destroy(slab_cache_t *cache, slab_magazine_t *mag) |
static count_t magazine_destroy(slab_cache_t *cache, |
slab_magazine_t *mag) |
{ |
unsigned int i; |
count_t frames = 0; |
387,7 → 389,7 |
* |
* Assume cpu_magazine lock is held |
*/ |
static slab_magazine_t *get_full_current_mag(slab_cache_t *cache) |
static slab_magazine_t * get_full_current_mag(slab_cache_t *cache) |
{ |
slab_magazine_t *cmag, *lastmag, *newmag; |
421,7 → 423,7 |
* |
* @return Pointer to object or NULL if not available |
*/ |
static void *magazine_obj_get(slab_cache_t *cache) |
static void * magazine_obj_get(slab_cache_t *cache) |
{ |
slab_magazine_t *mag; |
void *obj; |
456,7 → 458,7 |
* allocate new, exchange last & current |
* |
*/ |
static slab_magazine_t *make_empty_current_mag(slab_cache_t *cache) |
static slab_magazine_t * make_empty_current_mag(slab_cache_t *cache) |
{ |
slab_magazine_t *cmag,*lastmag,*newmag; |
528,8 → 530,7 |
static unsigned int comp_objects(slab_cache_t *cache) |
{ |
if (cache->flags & SLAB_CACHE_SLINSIDE) |
return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / |
cache->size; |
return ((PAGE_SIZE << cache->order) - sizeof(slab_t)) / cache->size; |
else |
return (PAGE_SIZE << cache->order) / cache->size; |
} |
556,25 → 557,28 |
ASSERT(_slab_initialized >= 2); |
cache->mag_cache = malloc(sizeof(slab_mag_cache_t) * config.cpu_count, |
0); |
cache->mag_cache = malloc(sizeof(slab_mag_cache_t)*config.cpu_count,0); |
for (i = 0; i < config.cpu_count; i++) { |
memsetb(&cache->mag_cache[i], sizeof(cache->mag_cache[i]), 0); |
spinlock_initialize(&cache->mag_cache[i].lock, |
"slab_maglock_cpu"); |
memsetb((uintptr_t)&cache->mag_cache[i], |
sizeof(cache->mag_cache[i]), 0); |
spinlock_initialize(&cache->mag_cache[i].lock, "slab_maglock_cpu"); |
} |
} |
/** Initialize allocated memory as a slab cache */ |
static void |
_slab_cache_create(slab_cache_t *cache, char *name, size_t size, size_t align, |
int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj), |
int flags) |
_slab_cache_create(slab_cache_t *cache, |
char *name, |
size_t size, |
size_t align, |
int (*constructor)(void *obj, int kmflag), |
int (*destructor)(void *obj), |
int flags) |
{ |
int pages; |
ipl_t ipl; |
memsetb(cache, sizeof(*cache), 0); |
memsetb((uintptr_t)cache, sizeof(*cache), 0); |
cache->name = name; |
if (align < sizeof(unative_t)) |
592,7 → 596,7 |
list_initialize(&cache->magazines); |
spinlock_initialize(&cache->slablock, "slab_lock"); |
spinlock_initialize(&cache->maglock, "slab_maglock"); |
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) |
if (! (cache->flags & SLAB_CACHE_NOMAGAZINE)) |
make_magcache(cache); |
/* Compute slab sizes, object counts in slabs etc. */ |
605,7 → 609,7 |
if (pages == 1) |
cache->order = 0; |
else |
cache->order = fnzb(pages - 1) + 1; |
cache->order = fnzb(pages-1)+1; |
while (badness(cache) > SLAB_MAX_BADNESS(cache)) { |
cache->order += 1; |
626,16 → 630,18 |
} |
/** Create slab cache */ |
slab_cache_t * |
slab_cache_create(char *name, size_t size, size_t align, |
int (*constructor)(void *obj, int kmflag), int (*destructor)(void *obj), |
int flags) |
slab_cache_t * slab_cache_create(char *name, |
size_t size, |
size_t align, |
int (*constructor)(void *obj, int kmflag), |
int (*destructor)(void *obj), |
int flags) |
{ |
slab_cache_t *cache; |
cache = slab_alloc(&slab_cache_cache, 0); |
_slab_cache_create(cache, name, size, align, constructor, destructor, |
flags); |
flags); |
return cache; |
} |
659,7 → 665,7 |
* endless loop |
*/ |
magcount = atomic_get(&cache->magazine_counter); |
while (magcount-- && (mag=get_mag_from_cache(cache, 0))) { |
while (magcount-- && (mag=get_mag_from_cache(cache,0))) { |
frames += magazine_destroy(cache,mag); |
if (!(flags & SLAB_RECLAIM_ALL) && frames) |
break; |
712,8 → 718,8 |
_slab_reclaim(cache, SLAB_RECLAIM_ALL); |
/* All slabs must be empty */ |
if (!list_empty(&cache->full_slabs) || |
!list_empty(&cache->partial_slabs)) |
if (!list_empty(&cache->full_slabs) \ |
|| !list_empty(&cache->partial_slabs)) |
panic("Destroying cache that is not empty."); |
if (!(cache->flags & SLAB_CACHE_NOMAGAZINE)) |
721,8 → 727,9 |
slab_free(&slab_cache_cache, cache); |
} |
/** Allocate new object from cache - if no flags given, always returns memory */ |
void *slab_alloc(slab_cache_t *cache, int flags) |
/** Allocate new object from cache - if no flags given, always returns |
memory */ |
void * slab_alloc(slab_cache_t *cache, int flags) |
{ |
ipl_t ipl; |
void *result = NULL; |
751,8 → 758,9 |
ipl = interrupts_disable(); |
if ((cache->flags & SLAB_CACHE_NOMAGAZINE) || |
magazine_obj_put(cache, obj)) { |
if ((cache->flags & SLAB_CACHE_NOMAGAZINE) \ |
|| magazine_obj_put(cache, obj)) { |
slab_obj_destroy(cache, obj, slab); |
} |
779,8 → 787,7 |
* memory allocation from interrupts can deadlock. |
*/ |
for (cur = slab_cache_list.next; cur != &slab_cache_list; |
cur = cur->next) { |
for (cur = slab_cache_list.next;cur!=&slab_cache_list; cur=cur->next) { |
cache = list_get_instance(cur, slab_cache_t, link); |
frames += _slab_reclaim(cache, flags); |
} |
794,77 → 801,22 |
/* Print list of slabs */ |
void slab_print_list(void) |
{ |
int skip = 0; |
printf("slab name size pages obj/pg slabs cached allocated" |
" ctl\n"); |
printf("---------------- -------- ------ ------ ------ ------ ---------" |
" ---\n"); |
while (true) { |
slab_cache_t *cache; |
link_t *cur; |
ipl_t ipl; |
int i; |
/* |
* We must not hold the slab_cache_lock spinlock when printing |
* the statistics. Otherwise we can easily deadlock if the print |
* needs to allocate memory. |
* |
* Therefore, we walk through the slab cache list, skipping some |
* amount of already processed caches during each iteration and |
* gathering statistics about the first unprocessed cache. For |
* the sake of printing the statistics, we realese the |
* slab_cache_lock and reacquire it afterwards. Then the walk |
* starts again. |
* |
* This limits both the efficiency and also accuracy of the |
* obtained statistics. The efficiency is decreased because the |
* time complexity of the algorithm is quadratic instead of |
* linear. The accuracy is impacted because we drop the lock |
* after processing one cache. If there is someone else |
* manipulating the cache list, we might omit an arbitrary |
* number of caches or process one cache multiple times. |
* However, we don't bleed for this algorithm for it is only |
* statistics. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&slab_cache_lock); |
for (i = 0, cur = slab_cache_list.next; |
i < skip && cur != &slab_cache_list; |
i++, cur = cur->next) |
; |
if (cur == &slab_cache_list) { |
spinlock_unlock(&slab_cache_lock); |
interrupts_restore(ipl); |
break; |
} |
skip++; |
slab_cache_t *cache; |
link_t *cur; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&slab_cache_lock); |
printf("slab name size pages obj/pg slabs cached allocated ctl\n"); |
printf("---------------- -------- ------ ------ ------ ------ --------- ---\n"); |
for (cur = slab_cache_list.next; cur != &slab_cache_list; cur = cur->next) { |
cache = list_get_instance(cur, slab_cache_t, link); |
char *name = cache->name; |
uint8_t order = cache->order; |
size_t size = cache->size; |
unsigned int objects = cache->objects; |
long allocated_slabs = atomic_get(&cache->allocated_slabs); |
long cached_objs = atomic_get(&cache->cached_objs); |
long allocated_objs = atomic_get(&cache->allocated_objs); |
int flags = cache->flags; |
spinlock_unlock(&slab_cache_lock); |
interrupts_restore(ipl); |
printf("%-16s %8" PRIs " %6d %6u %6ld %6ld %9ld %-3s\n", |
name, size, (1 << order), objects, allocated_slabs, |
cached_objs, allocated_objs, |
flags & SLAB_CACHE_SLINSIDE ? "in" : "out"); |
printf("%-16s %8zd %6zd %6zd %6zd %6zd %9zd %-3s\n", cache->name, cache->size, (1 << cache->order), cache->objects, atomic_get(&cache->allocated_slabs), atomic_get(&cache->cached_objs), atomic_get(&cache->allocated_objs), cache->flags & SLAB_CACHE_SLINSIDE ? "in" : "out"); |
} |
spinlock_unlock(&slab_cache_lock); |
interrupts_restore(ipl); |
} |
void slab_cache_init(void) |
872,24 → 824,32 |
int i, size; |
/* Initialize magazine cache */ |
_slab_cache_create(&mag_cache, "slab_magazine", |
sizeof(slab_magazine_t) + SLAB_MAG_SIZE * sizeof(void*), |
sizeof(uintptr_t), NULL, NULL, SLAB_CACHE_NOMAGAZINE | |
SLAB_CACHE_SLINSIDE); |
_slab_cache_create(&mag_cache, |
"slab_magazine", |
sizeof(slab_magazine_t)+SLAB_MAG_SIZE*sizeof(void*), |
sizeof(uintptr_t), |
NULL, NULL, |
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE); |
/* Initialize slab_cache cache */ |
_slab_cache_create(&slab_cache_cache, "slab_cache", |
sizeof(slab_cache_cache), sizeof(uintptr_t), NULL, NULL, |
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE); |
_slab_cache_create(&slab_cache_cache, |
"slab_cache", |
sizeof(slab_cache_cache), |
sizeof(uintptr_t), |
NULL, NULL, |
SLAB_CACHE_NOMAGAZINE | SLAB_CACHE_SLINSIDE); |
/* Initialize external slab cache */ |
slab_extern_cache = slab_cache_create("slab_extern", sizeof(slab_t), 0, |
NULL, NULL, SLAB_CACHE_SLINSIDE | SLAB_CACHE_MAGDEFERRED); |
slab_extern_cache = slab_cache_create("slab_extern", |
sizeof(slab_t), |
0, NULL, NULL, |
SLAB_CACHE_SLINSIDE | SLAB_CACHE_MAGDEFERRED); |
/* Initialize structures for malloc */ |
for (i = 0, size = (1 << SLAB_MIN_MALLOC_W); |
i < (SLAB_MAX_MALLOC_W - SLAB_MIN_MALLOC_W + 1); |
i++, size <<= 1) { |
malloc_caches[i] = slab_cache_create(malloc_names[i], size, 0, |
NULL, NULL, SLAB_CACHE_MAGDEFERRED); |
for (i=0, size=(1<<SLAB_MIN_MALLOC_W); |
i < (SLAB_MAX_MALLOC_W-SLAB_MIN_MALLOC_W+1); |
i++, size <<= 1) { |
malloc_caches[i] = slab_cache_create(malloc_names[i], |
size, 0, |
NULL,NULL, SLAB_CACHE_MAGDEFERRED); |
} |
#ifdef CONFIG_DEBUG |
_slab_initialized = 1; |
914,11 → 874,9 |
spinlock_lock(&slab_cache_lock); |
for (cur = slab_cache_list.next; cur != &slab_cache_list; |
cur = cur->next){ |
for (cur=slab_cache_list.next; cur != &slab_cache_list;cur=cur->next){ |
s = list_get_instance(cur, slab_cache_t, link); |
if ((s->flags & SLAB_CACHE_MAGDEFERRED) != |
SLAB_CACHE_MAGDEFERRED) |
if ((s->flags & SLAB_CACHE_MAGDEFERRED) != SLAB_CACHE_MAGDEFERRED) |
continue; |
make_magcache(s); |
s->flags &= ~SLAB_CACHE_MAGDEFERRED; |
929,7 → 887,7 |
/**************************************/ |
/* kalloc/kfree functions */ |
void *malloc(unsigned int size, int flags) |
void * malloc(unsigned int size, int flags) |
{ |
ASSERT(_slab_initialized); |
ASSERT(size && size <= (1 << SLAB_MAX_MALLOC_W)); |
942,7 → 900,7 |
return slab_alloc(malloc_caches[idx], flags); |
} |
void *realloc(void *ptr, unsigned int size, int flags) |
void * realloc(void *ptr, unsigned int size, int flags) |
{ |
ASSERT(_slab_initialized); |
ASSERT(size <= (1 << SLAB_MAX_MALLOC_W)); |
/branches/dd/kernel/generic/src/mm/tlb.c |
---|
173,7 → 173,7 |
tlb_invalidate_pages(asid, page, count); |
break; |
default: |
panic("Unknown type (%d).", type); |
panic("unknown type (%d)\n", type); |
break; |
} |
if (type == TLB_INVL_ALL) |
/branches/dd/kernel/generic/src/mm/backend_anon.c |
---|
78,6 → 78,7 |
int anon_page_fault(as_area_t *area, uintptr_t addr, pf_access_t access) |
{ |
uintptr_t frame; |
bool dirty = false; |
if (!as_area_check_access(area, access)) |
return AS_PF_FAULT; |
105,7 → 106,7 |
*/ |
for (i = 0; i < leaf->keys; i++) { |
if (leaf->key[i] == |
ALIGN_DOWN(addr, PAGE_SIZE) - area->base) { |
ALIGN_DOWN(addr, PAGE_SIZE)) { |
allocate = false; |
break; |
} |
112,7 → 113,8 |
} |
if (allocate) { |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
/* |
* Insert the address of the newly allocated |
142,7 → 144,8 |
* the different causes |
*/ |
frame = (uintptr_t) frame_alloc(ONE_FRAME, 0); |
memsetb((void *) PA2KA(frame), FRAME_SIZE, 0); |
memsetb(PA2KA(frame), FRAME_SIZE, 0); |
dirty = true; |
} |
/* |
152,7 → 155,7 |
*/ |
page_mapping_insert(AS, addr, frame, as_area_get_flags(area)); |
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
panic("Cannot insert used space."); |
panic("Could not insert used space.\n"); |
return AS_PF_OK; |
} |
/branches/dd/kernel/generic/src/mm/as.c |
---|
82,6 → 82,7 |
#include <arch/mm/cache.h> |
#endif /* CONFIG_VIRT_IDX_DCACHE */ |
#ifndef __OBJC__ |
/** |
* Each architecture decides what functions will be used to carry out |
* address space operations such as creating or locking page tables. |
92,6 → 93,7 |
* Slab for as_t objects. |
*/ |
static slab_cache_t *as_slab; |
#endif |
/** |
* This lock serializes access to the ASID subsystem. |
111,11 → 113,13 |
/** Kernel address space. */ |
as_t *AS_KERNEL = NULL; |
static int area_flags_to_page_flags(int); |
static as_area_t *find_area_and_lock(as_t *, uintptr_t); |
static bool check_area_conflicts(as_t *, uintptr_t, size_t, as_area_t *); |
static void sh_info_remove_reference(share_info_t *); |
static int area_flags_to_page_flags(int aflags); |
static as_area_t *find_area_and_lock(as_t *as, uintptr_t va); |
static bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, |
as_area_t *avoid_area); |
static void sh_info_remove_reference(share_info_t *sh_info); |
#ifndef __OBJC__ |
static int as_constructor(void *obj, int flags) |
{ |
as_t *as = (as_t *) obj; |
122,7 → 126,7 |
int rc; |
link_initialize(&as->inactive_as_with_asid_link); |
mutex_initialize(&as->lock, MUTEX_PASSIVE); |
mutex_initialize(&as->lock); |
rc = as_constructor_arch(as, flags); |
135,6 → 139,7 |
return as_destructor_arch(as); |
} |
#endif |
/** Initialize address space subsystem. */ |
void as_init(void) |
141,29 → 146,33 |
{ |
as_arch_init(); |
#ifndef __OBJC__ |
as_slab = slab_cache_create("as_slab", sizeof(as_t), 0, |
as_constructor, as_destructor, SLAB_CACHE_MAGDEFERRED); |
#endif |
AS_KERNEL = as_create(FLAG_AS_KERNEL); |
if (!AS_KERNEL) |
panic("Cannot create kernel address space."); |
panic("can't create kernel address space\n"); |
/* Make sure the kernel address space |
* reference count never drops to zero. |
*/ |
atomic_set(&AS_KERNEL->refcount, 1); |
} |
/** Create address space. |
* |
* @param flags Flags that influence the way in wich the address space |
* is created. |
* @param flags Flags that influence way in wich the address space is created. |
*/ |
as_t *as_create(int flags) |
{ |
as_t *as; |
#ifdef __OBJC__ |
as = [as_t new]; |
link_initialize(&as->inactive_as_with_asid_link); |
mutex_initialize(&as->lock); |
(void) as_constructor_arch(as, flags); |
#else |
as = (as_t *) slab_alloc(as_slab, 0); |
#endif |
(void) as_create_arch(as, 0); |
btree_create(&as->as_area_btree); |
180,7 → 189,7 |
#else |
page_table_create(flags); |
#endif |
return as; |
} |
190,8 → 199,6 |
* zero), the address space can be destroyed. |
* |
* We know that we don't hold any spinlock. |
* |
* @param as Address space to be destroyed. |
*/ |
void as_destroy(as_t *as) |
{ |
256,7 → 263,11 |
interrupts_restore(ipl); |
#ifdef __OBJC__ |
[as free]; |
#else |
slab_free(as_slab, as); |
#endif |
} |
/** Create address space area of common attributes. |
263,19 → 274,19 |
* |
* The created address space area is added to the target address space. |
* |
* @param as Target address space. |
* @param flags Flags of the area memory. |
* @param size Size of area. |
* @param base Base address of area. |
* @param attrs Attributes of the area. |
* @param backend Address space area backend. NULL if no backend is used. |
* @param backend_data NULL or a pointer to an array holding two void *. |
* @param as Target address space. |
* @param flags Flags of the area memory. |
* @param size Size of area. |
* @param base Base address of area. |
* @param attrs Attributes of the area. |
* @param backend Address space area backend. NULL if no backend is used. |
* @param backend_data NULL or a pointer to an array holding two void *. |
* |
* @return Address space area on success or NULL on failure. |
* @return Address space area on success or NULL on failure. |
*/ |
as_area_t * |
as_area_create(as_t *as, int flags, size_t size, uintptr_t base, int attrs, |
mem_backend_t *backend, mem_backend_data_t *backend_data) |
mem_backend_t *backend, mem_backend_data_t *backend_data) |
{ |
ipl_t ipl; |
as_area_t *a; |
301,7 → 312,7 |
a = (as_area_t *) malloc(sizeof(as_area_t), 0); |
mutex_initialize(&a->lock, MUTEX_PASSIVE); |
mutex_initialize(&a->lock); |
a->as = as; |
a->flags = flags; |
313,7 → 324,8 |
if (backend_data) |
a->backend_data = *backend_data; |
else |
memsetb(&a->backend_data, sizeof(a->backend_data), 0); |
memsetb((uintptr_t) &a->backend_data, sizeof(a->backend_data), |
0); |
btree_create(&a->used_space); |
327,14 → 339,13 |
/** Find address space area and change it. |
* |
* @param as Address space. |
* @param address Virtual address belonging to the area to be changed. |
* Must be page-aligned. |
* @param size New size of the virtual memory block starting at |
* address. |
* @param flags Flags influencing the remap operation. Currently unused. |
* @param as Address space. |
* @param address Virtual address belonging to the area to be changed. Must be |
* page-aligned. |
* @param size New size of the virtual memory block starting at address. |
* @param flags Flags influencing the remap operation. Currently unused. |
* |
* @return Zero on success or a value from @ref errno.h otherwise. |
* @return Zero on success or a value from @ref errno.h otherwise. |
*/ |
int as_area_resize(as_t *as, uintptr_t address, size_t size, int flags) |
{ |
389,7 → 400,7 |
if (pages < area->pages) { |
bool cond; |
uintptr_t start_free = area->base + pages * PAGE_SIZE; |
uintptr_t start_free = area->base + pages*PAGE_SIZE; |
/* |
* Shrinking the area. |
399,7 → 410,7 |
/* |
* Start TLB shootdown sequence. |
*/ |
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base + |
tlb_shootdown_start(TLB_INVL_PAGES, AS->asid, area->base + |
pages * PAGE_SIZE, area->pages - pages); |
/* |
444,8 → 455,8 |
i = (start_free - b) >> PAGE_WIDTH; |
if (!used_space_remove(area, start_free, |
c - i)) |
panic("Cannot remove used " |
"space."); |
panic("Could not remove used " |
"space.\n"); |
} else { |
/* |
* The interval of used space can be |
452,8 → 463,8 |
* completely removed. |
*/ |
if (!used_space_remove(area, b, c)) |
panic("Cannot remove used " |
"space."); |
panic("Could not remove used " |
"space.\n"); |
} |
for (; i < c; i++) { |
515,10 → 526,10 |
/** Destroy address space area. |
* |
* @param as Address space. |
* @param address Address within the area to be deleted. |
* @param as Address space. |
* @param address Address withing the area to be deleted. |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
* @return Zero on success or a value from @ref errno.h on failure. |
*/ |
int as_area_destroy(as_t *as, uintptr_t address) |
{ |
615,19 → 626,18 |
* sh_info of the source area. The process of duplicating the |
* mapping is done through the backend share function. |
* |
* @param src_as Pointer to source address space. |
* @param src_base Base address of the source address space area. |
* @param acc_size Expected size of the source area. |
* @param dst_as Pointer to destination address space. |
* @param dst_base Target base address. |
* @param src_as Pointer to source address space. |
* @param src_base Base address of the source address space area. |
* @param acc_size Expected size of the source area. |
* @param dst_as Pointer to destination address space. |
* @param dst_base Target base address. |
* @param dst_flags_mask Destination address space area flags mask. |
* |
* @return Zero on success or ENOENT if there is no such task or if |
* there is no such address space area, EPERM if there was |
* a problem in accepting the area or ENOMEM if there was a |
* problem in allocating destination address space area. |
* ENOTSUP is returned if the address space area backend |
* does not support sharing. |
* @return Zero on success or ENOENT if there is no such task or if there is no |
* such address space area, EPERM if there was a problem in accepting the area |
* or ENOMEM if there was a problem in allocating destination address space |
* area. ENOTSUP is returned if the address space area backend does not support |
* sharing. |
*/ |
int as_area_share(as_t *src_as, uintptr_t src_base, size_t acc_size, |
as_t *dst_as, uintptr_t dst_base, int dst_flags_mask) |
688,7 → 698,7 |
sh_info = src_area->sh_info; |
if (!sh_info) { |
sh_info = (share_info_t *) malloc(sizeof(share_info_t), 0); |
mutex_initialize(&sh_info->lock, MUTEX_PASSIVE); |
mutex_initialize(&sh_info->lock); |
sh_info->refcount = 2; |
btree_create(&sh_info->pagemap); |
src_area->sh_info = sh_info; |
746,11 → 756,10 |
* |
* The address space area must be locked prior to this call. |
* |
* @param area Address space area. |
* @param access Access mode. |
* @param area Address space area. |
* @param access Access mode. |
* |
* @return False if access violates area's permissions, true |
* otherwise. |
* @return False if access violates area's permissions, true otherwise. |
*/ |
bool as_area_check_access(as_area_t *area, pf_access_t access) |
{ |
766,183 → 775,21 |
return true; |
} |
/** Change adress space area flags. |
* |
* The idea is to have the same data, but with a different access mode. |
* This is needed e.g. for writing code into memory and then executing it. |
* In order for this to work properly, this may copy the data |
* into private anonymous memory (unless it's already there). |
* |
* @param as Address space. |
* @param flags Flags of the area memory. |
* @param address Address within the area to be changed. |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
* |
*/ |
int as_area_change_flags(as_t *as, int flags, uintptr_t address) |
{ |
as_area_t *area; |
uintptr_t base; |
link_t *cur; |
ipl_t ipl; |
int page_flags; |
uintptr_t *old_frame; |
index_t frame_idx; |
count_t used_pages; |
/* Flags for the new memory mapping */ |
page_flags = area_flags_to_page_flags(flags); |
ipl = interrupts_disable(); |
mutex_lock(&as->lock); |
area = find_area_and_lock(as, address); |
if (!area) { |
mutex_unlock(&as->lock); |
interrupts_restore(ipl); |
return ENOENT; |
} |
if ((area->sh_info) || (area->backend != &anon_backend)) { |
/* Copying shared areas not supported yet */ |
/* Copying non-anonymous memory not supported yet */ |
mutex_unlock(&area->lock); |
mutex_unlock(&as->lock); |
interrupts_restore(ipl); |
return ENOTSUP; |
} |
base = area->base; |
/* |
* Compute total number of used pages in the used_space B+tree |
*/ |
used_pages = 0; |
for (cur = area->used_space.leaf_head.next; |
cur != &area->used_space.leaf_head; cur = cur->next) { |
btree_node_t *node; |
unsigned int i; |
node = list_get_instance(cur, btree_node_t, leaf_link); |
for (i = 0; i < node->keys; i++) { |
used_pages += (count_t) node->value[i]; |
} |
} |
/* An array for storing frame numbers */ |
old_frame = malloc(used_pages * sizeof(uintptr_t), 0); |
/* |
* Start TLB shootdown sequence. |
*/ |
tlb_shootdown_start(TLB_INVL_PAGES, as->asid, area->base, area->pages); |
/* |
* Remove used pages from page tables and remember their frame |
* numbers. |
*/ |
frame_idx = 0; |
for (cur = area->used_space.leaf_head.next; |
cur != &area->used_space.leaf_head; cur = cur->next) { |
btree_node_t *node; |
unsigned int i; |
node = list_get_instance(cur, btree_node_t, leaf_link); |
for (i = 0; i < node->keys; i++) { |
uintptr_t b = node->key[i]; |
count_t j; |
pte_t *pte; |
for (j = 0; j < (count_t) node->value[i]; j++) { |
page_table_lock(as, false); |
pte = page_mapping_find(as, b + j * PAGE_SIZE); |
ASSERT(pte && PTE_VALID(pte) && |
PTE_PRESENT(pte)); |
old_frame[frame_idx++] = PTE_GET_FRAME(pte); |
/* Remove old mapping */ |
page_mapping_remove(as, b + j * PAGE_SIZE); |
page_table_unlock(as, false); |
} |
} |
} |
/* |
* Finish TLB shootdown sequence. |
*/ |
tlb_invalidate_pages(as->asid, area->base, area->pages); |
/* |
* Invalidate potential software translation caches (e.g. TSB on |
* sparc64). |
*/ |
as_invalidate_translation_cache(as, area->base, area->pages); |
tlb_shootdown_finalize(); |
/* |
* Set the new flags. |
*/ |
area->flags = flags; |
/* |
* Map pages back in with new flags. This step is kept separate |
* so that the memory area could not be accesed with both the old and |
* the new flags at once. |
*/ |
frame_idx = 0; |
for (cur = area->used_space.leaf_head.next; |
cur != &area->used_space.leaf_head; cur = cur->next) { |
btree_node_t *node; |
unsigned int i; |
node = list_get_instance(cur, btree_node_t, leaf_link); |
for (i = 0; i < node->keys; i++) { |
uintptr_t b = node->key[i]; |
count_t j; |
for (j = 0; j < (count_t) node->value[i]; j++) { |
page_table_lock(as, false); |
/* Insert the new mapping */ |
page_mapping_insert(as, b + j * PAGE_SIZE, |
old_frame[frame_idx++], page_flags); |
page_table_unlock(as, false); |
} |
} |
} |
free(old_frame); |
mutex_unlock(&area->lock); |
mutex_unlock(&as->lock); |
interrupts_restore(ipl); |
return 0; |
} |
/** Handle page fault within the current address space. |
* |
* This is the high-level page fault handler. It decides whether the page fault |
* can be resolved by any backend and if so, it invokes the backend to resolve |
* the page fault. |
* This is the high-level page fault handler. It decides |
* whether the page fault can be resolved by any backend |
* and if so, it invokes the backend to resolve the page |
* fault. |
* |
* Interrupts are assumed disabled. |
* |
* @param page Faulting page. |
* @param access Access mode that caused the page fault (i.e. |
* read/write/exec). |
* @param istate Pointer to the interrupted state. |
* @param page Faulting page. |
* @param access Access mode that caused the fault (i.e. read/write/exec). |
* @param istate Pointer to interrupted state. |
* |
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or |
* AS_PF_DEFER if the fault was caused by copy_to_uspace() |
* or copy_from_uspace(). |
* @return AS_PF_FAULT on page fault, AS_PF_OK on success or AS_PF_DEFER if the |
* fault was caused by copy_to_uspace() or copy_from_uspace(). |
*/ |
int as_page_fault(uintptr_t page, pf_access_t access, istate_t *istate) |
{ |
988,8 → 835,9 |
page_table_lock(AS, false); |
/* |
* To avoid race condition between two page faults on the same address, |
* we need to make sure the mapping has not been already inserted. |
* To avoid race condition between two page faults |
* on the same address, we need to make sure |
* the mapping has not been already inserted. |
*/ |
if ((pte = page_mapping_find(AS, page))) { |
if (PTE_PRESENT(pte)) { |
1043,8 → 891,8 |
* |
* When this function is enetered, no spinlocks may be held. |
* |
* @param old Old address space or NULL. |
* @param new New address space. |
* @param old Old address space or NULL. |
* @param new New address space. |
*/ |
void as_switch(as_t *old_as, as_t *new_as) |
{ |
1115,9 → 963,9 |
/** Convert address space area flags to page flags. |
* |
* @param aflags Flags of some address space area. |
* @param aflags Flags of some address space area. |
* |
* @return Flags to be passed to page_mapping_insert(). |
* @return Flags to be passed to page_mapping_insert(). |
*/ |
int area_flags_to_page_flags(int aflags) |
{ |
1145,9 → 993,9 |
* The address space area must be locked. |
* Interrupts must be disabled. |
* |
* @param a Address space area. |
* @param a Address space area. |
* |
* @return Flags to be used in page_mapping_insert(). |
* @return Flags to be used in page_mapping_insert(). |
*/ |
int as_area_get_flags(as_area_t *a) |
{ |
1156,20 → 1004,23 |
/** Create page table. |
* |
* Depending on architecture, create either address space private or global page |
* table. |
* Depending on architecture, create either address space |
* private or global page table. |
* |
* @param flags Flags saying whether the page table is for the kernel |
* address space. |
* @param flags Flags saying whether the page table is for kernel address space. |
* |
* @return First entry of the page table. |
* @return First entry of the page table. |
*/ |
pte_t *page_table_create(int flags) |
{ |
#ifdef __OBJC__ |
return [as_t page_table_create: flags]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_create); |
return as_operations->page_table_create(flags); |
#endif |
} |
/** Destroy page table. |
1176,14 → 1027,18 |
* |
* Destroy page table in architecture specific way. |
* |
* @param page_table Physical address of PTL0. |
* @param page_table Physical address of PTL0. |
*/ |
void page_table_destroy(pte_t *page_table) |
{ |
#ifdef __OBJC__ |
return [as_t page_table_destroy: page_table]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_destroy); |
as_operations->page_table_destroy(page_table); |
#endif |
} |
/** Lock page table. |
1195,28 → 1050,36 |
* prior to this call. Address space can be locked prior to this |
* call in which case the lock argument is false. |
* |
* @param as Address space. |
* @param lock If false, do not attempt to lock as->lock. |
* @param as Address space. |
* @param lock If false, do not attempt to lock as->lock. |
*/ |
void page_table_lock(as_t *as, bool lock) |
{ |
#ifdef __OBJC__ |
[as page_table_lock: lock]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_lock); |
as_operations->page_table_lock(as, lock); |
#endif |
} |
/** Unlock page table. |
* |
* @param as Address space. |
* @param unlock If false, do not attempt to unlock as->lock. |
* @param as Address space. |
* @param unlock If false, do not attempt to unlock as->lock. |
*/ |
void page_table_unlock(as_t *as, bool unlock) |
{ |
#ifdef __OBJC__ |
[as page_table_unlock: unlock]; |
#else |
ASSERT(as_operations); |
ASSERT(as_operations->page_table_unlock); |
as_operations->page_table_unlock(as, unlock); |
#endif |
} |
1224,11 → 1087,11 |
* |
* The address space must be locked and interrupts must be disabled. |
* |
* @param as Address space. |
* @param va Virtual address. |
* @param as Address space. |
* @param va Virtual address. |
* |
* @return Locked address space area containing va on success or |
* NULL on failure. |
* @return Locked address space area containing va on success or NULL on |
* failure. |
*/ |
as_area_t *find_area_and_lock(as_t *as, uintptr_t va) |
{ |
1280,15 → 1143,15 |
* |
* The address space must be locked and interrupts must be disabled. |
* |
* @param as Address space. |
* @param va Starting virtual address of the area being tested. |
* @param size Size of the area being tested. |
* @param avoid_area Do not touch this area. |
* @param as Address space. |
* @param va Starting virtual address of the area being tested. |
* @param size Size of the area being tested. |
* @param avoid_area Do not touch this area. |
* |
* @return True if there is no conflict, false otherwise. |
* @return True if there is no conflict, false otherwise. |
*/ |
bool |
check_area_conflicts(as_t *as, uintptr_t va, size_t size, as_area_t *avoid_area) |
bool check_area_conflicts(as_t *as, uintptr_t va, size_t size, |
as_area_t *avoid_area) |
{ |
as_area_t *a; |
btree_node_t *leaf, *node; |
1377,7 → 1240,7 |
ipl = interrupts_disable(); |
src_area = find_area_and_lock(AS, base); |
if (src_area) { |
if (src_area){ |
size = src_area->pages * PAGE_SIZE; |
mutex_unlock(&src_area->lock); |
} else { |
1391,11 → 1254,11 |
* |
* The address space area must be already locked. |
* |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* |
* @return Zero on failure and non-zero on success. |
* @return 0 on failure and 1 on success. |
*/ |
int used_space_insert(as_area_t *a, uintptr_t page, count_t count) |
{ |
1665,8 → 1528,8 |
} |
} |
panic("Inconsistency detected while adding %" PRIc " pages of used " |
"space at %p.", count, page); |
panic("Inconsistency detected while adding %d pages of used space at " |
"%p.\n", count, page); |
} |
/** Mark portion of address space area as unused. |
1673,11 → 1536,11 |
* |
* The address space area must be already locked. |
* |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* @param a Address space area. |
* @param page First page to be marked. |
* @param count Number of page to be marked. |
* |
* @return Zero on failure and non-zero on success. |
* @return 0 on failure and 1 on success. |
*/ |
int used_space_remove(as_area_t *a, uintptr_t page, count_t count) |
{ |
1844,8 → 1707,8 |
} |
error: |
panic("Inconsistency detected while removing %" PRIc " pages of used " |
"space from %p.", count, page); |
panic("Inconsistency detected while removing %d pages of used space " |
"from %p.\n", count, page); |
} |
/** Remove reference to address space area share info. |
1852,7 → 1715,7 |
* |
* If the reference count drops to 0, the sh_info is deallocated. |
* |
* @param sh_info Pointer to address space area share info. |
* @param sh_info Pointer to address space area share info. |
*/ |
void sh_info_remove_reference(share_info_t *sh_info) |
{ |
1907,12 → 1770,6 |
return (unative_t) as_area_resize(AS, address, size, 0); |
} |
/** Wrapper for as_area_change_flags(). */ |
unative_t sys_as_area_change_flags(uintptr_t address, int flags) |
{ |
return (unative_t) as_area_change_flags(AS, flags, address); |
} |
/** Wrapper for as_area_destroy(). */ |
unative_t sys_as_area_destroy(uintptr_t address) |
{ |
1921,7 → 1778,7 |
/** Print out information about address space. |
* |
* @param as Address space. |
* @param as Address space. |
*/ |
void as_print(as_t *as) |
{ |
1943,9 → 1800,9 |
as_area_t *area = node->value[i]; |
mutex_lock(&area->lock); |
printf("as_area: %p, base=%p, pages=%" PRIc |
" (%p - %p)\n", area, area->base, area->pages, |
area->base, area->base + FRAMES2SIZE(area->pages)); |
printf("as_area: %p, base=%p, pages=%d (%p - %p)\n", |
area, area->base, area->pages, area->base, |
area->base + area->pages*PAGE_SIZE); |
mutex_unlock(&area->lock); |
} |
} |
/branches/dd/kernel/generic/src/mm/frame.c |
---|
1,7 → 1,6 |
/* |
* Copyright (c) 2001-2005 Jakub Jermar |
* Copyright (c) 2005 Sergey Bondari |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
34,7 → 33,7 |
/** |
* @file |
* @brief Physical frame allocator. |
* @brief Physical frame allocator. |
* |
* This file contains the physical frame allocator and memory zone management. |
* The frame allocator is built on top of the buddy allocator. |
42,6 → 41,16 |
* @see buddy.c |
*/ |
/* |
* Locking order |
* |
* In order to access particular zone, the process must first lock |
* the zones.lock, then lock the zone and then unlock the zones.lock. |
* This insures, that we can fiddle with the zones in runtime without |
* affecting the processes. |
* |
*/ |
#include <arch/types.h> |
#include <mm/frame.h> |
#include <mm/as.h> |
48,8 → 57,7 |
#include <panic.h> |
#include <debug.h> |
#include <adt/list.h> |
#include <synch/mutex.h> |
#include <synch/condvar.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <print.h> |
59,17 → 67,43 |
#include <macros.h> |
#include <config.h> |
zones_t zones; |
typedef struct { |
count_t refcount; /**< tracking of shared frames */ |
uint8_t buddy_order; /**< buddy system block order */ |
link_t buddy_link; /**< link to the next free block inside one |
order */ |
void *parent; /**< If allocated by slab, this points there */ |
} frame_t; |
typedef struct { |
SPINLOCK_DECLARE(lock); /**< this lock protects everything below */ |
pfn_t base; /**< frame_no of the first frame in the frames |
array */ |
count_t count; /**< Size of zone */ |
frame_t *frames; /**< array of frame_t structures in this |
zone */ |
count_t free_count; /**< number of free frame_t structures */ |
count_t busy_count; /**< number of busy frame_t structures */ |
buddy_system_t *buddy_system; /**< buddy system for the zone */ |
int flags; |
} zone_t; |
/* |
* Synchronization primitives used to sleep when there is no memory |
* available. |
* The zoneinfo.lock must be locked when accessing zoneinfo structure. |
* Some of the attributes in zone_t structures are 'read-only' |
*/ |
mutex_t mem_avail_mtx; |
condvar_t mem_avail_cv; |
count_t mem_avail_req = 0; /**< Number of frames requested. */ |
count_t mem_avail_gen = 0; /**< Generation counter. */ |
typedef struct { |
SPINLOCK_DECLARE(lock); |
unsigned int count; |
zone_t *info[ZONES_MAX]; |
} zones_t; |
static zones_t zones; |
/********************/ |
/* Helper functions */ |
/********************/ |
84,20 → 118,22 |
return (index_t) (frame - zone->frames) + zone->base; |
} |
static inline bool frame_index_valid(zone_t *zone, index_t index) |
static inline int frame_index_valid(zone_t *zone, index_t index) |
{ |
return (index < zone->count); |
} |
static inline index_t make_frame_index(zone_t *zone, frame_t *frame) |
/** Compute pfn_t from frame_t pointer & zone pointer */ |
static index_t make_frame_index(zone_t *zone, frame_t *frame) |
{ |
return (frame - zone->frames); |
} |
/** Initialize frame structure. |
/** Initialize frame structure |
* |
* Initialize frame structure. |
* |
* @param frame Frame structure to be initialized. |
* |
*/ |
static void frame_initialize(frame_t *frame) |
{ |
105,145 → 141,142 |
frame->buddy_order = 0; |
} |
/*******************/ |
/* Zones functions */ |
/*******************/ |
/**********************/ |
/* Zoneinfo functions */ |
/**********************/ |
/** Insert-sort zone into zones list. |
/** |
* Insert-sort zone into zones list |
* |
* Assume interrupts are disabled and zones lock is |
* locked. |
* |
* @param base Base frame of the newly inserted zone. |
* @param count Number of frames of the newly inserted zone. |
* |
* @return Zone number on success, -1 on error. |
* |
* @param newzone New zone to be inserted into zone list |
* @return zone number on success, -1 on error |
*/ |
static count_t zones_insert_zone(pfn_t base, count_t count) |
static int zones_add_zone(zone_t *newzone) |
{ |
unsigned int i, j; |
ipl_t ipl; |
zone_t *z; |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
/* Try to merge */ |
if (zones.count + 1 == ZONES_MAX) { |
printf("Maximum zone count %u exceeded!\n", ZONES_MAX); |
return (count_t) -1; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return -1; |
} |
count_t i; |
for (i = 0; i < zones.count; i++) { |
/* Check for overlap */ |
if (overlaps(base, count, |
zones.info[i].base, zones.info[i].count)) { |
/* Check for overflow */ |
z = zones.info[i]; |
if (overlaps(newzone->base, newzone->count, z->base, z->count)) { |
printf("Zones overlap!\n"); |
return (count_t) -1; |
return -1; |
} |
if (base < zones.info[i].base) |
if (newzone->base < z->base) |
break; |
} |
/* Move other zones up */ |
count_t j; |
for (j = zones.count; j > i; j--) { |
zones.info[j] = zones.info[j - 1]; |
zones.info[j].buddy_system->data = |
(void *) &zones.info[j - 1]; |
} |
for (j = i; j < zones.count; j++) |
zones.info[j + 1] = zones.info[j]; |
zones.info[i] = newzone; |
zones.count++; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return i; |
} |
/** Get total available frames. |
/** |
* Try to find a zone where can we find the frame |
* |
* Assume interrupts are disabled and zones lock is |
* locked. |
* Assume interrupts are disabled. |
* |
* @return Total number of available frames. |
* |
* @param frame Frame number contained in zone |
* @param pzone If not null, it is used as zone hint. Zone index |
* is filled into the variable on success. |
* @return Pointer to locked zone containing frame |
*/ |
#ifdef CONFIG_DEBUG |
static count_t total_frames_free(void) |
static zone_t * find_zone_and_lock(pfn_t frame, unsigned int *pzone) |
{ |
count_t total = 0; |
count_t i; |
for (i = 0; i < zones.count; i++) |
total += zones.info[i].free_count; |
unsigned int i; |
unsigned int hint = pzone ? *pzone : 0; |
zone_t *z; |
return total; |
} |
#endif |
spinlock_lock(&zones.lock); |
/** Find a zone with a given frames. |
* |
* Assume interrupts are disabled and zones lock is |
* locked. |
* |
* @param frame Frame number contained in zone. |
* @param count Number of frames to look for. |
* @param hint Used as zone hint. |
* |
* @return Zone index or -1 if not found. |
* |
*/ |
count_t find_zone(pfn_t frame, count_t count, count_t hint) |
{ |
if (hint >= zones.count) |
hint = 0; |
count_t i = hint; |
i = hint; |
do { |
if ((zones.info[i].base <= frame) |
&& (zones.info[i].base + zones.info[i].count >= frame + count)) |
return i; |
z = zones.info[i]; |
spinlock_lock(&z->lock); |
if (z->base <= frame && z->base + z->count > frame) { |
/* Unlock the global lock */ |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
} |
spinlock_unlock(&z->lock); |
i++; |
if (i >= zones.count) |
i = 0; |
} while (i != hint); |
return (count_t) -1; |
} while(i != hint); |
spinlock_unlock(&zones.lock); |
return NULL; |
} |
/** @return True if zone can allocate specified order */ |
static bool zone_can_alloc(zone_t *zone, uint8_t order) |
static int zone_can_alloc(zone_t *z, uint8_t order) |
{ |
return (zone_flags_available(zone->flags) |
&& buddy_system_can_alloc(zone->buddy_system, order)); |
return buddy_system_can_alloc(z->buddy_system, order); |
} |
/** Find a zone that can allocate order frames. |
/** Find and lock zone that can allocate order frames. |
* |
* Assume interrupts are disabled and zones lock is |
* locked. |
* Assume interrupts are disabled. |
* |
* @param order Size (2^order) of free space we are trying to find. |
* @param flags Required flags of the target zone. |
* @param hind Preferred zone. |
* |
* @param order Size (2^order) of free space we are trying to find |
* @param pzone Pointer to preferred zone or NULL, on return contains zone |
* number |
*/ |
static count_t find_free_zone(uint8_t order, zone_flags_t flags, count_t hint) |
static zone_t * find_free_zone_and_lock(uint8_t order, unsigned int *pzone) |
{ |
unsigned int i; |
zone_t *z; |
unsigned int hint = pzone ? *pzone : 0; |
spinlock_lock(&zones.lock); |
if (hint >= zones.count) |
hint = 0; |
count_t i = hint; |
i = hint; |
do { |
/* |
* Check whether the zone meets the search criteria. |
*/ |
if ((zones.info[i].flags & flags) == flags) { |
/* |
* Check if the zone has 2^order frames area available. |
*/ |
if (zone_can_alloc(&zones.info[i], order)) |
return i; |
z = zones.info[i]; |
spinlock_lock(&z->lock); |
/* Check if the zone has 2^order frames area available */ |
if (zone_can_alloc(z, order)) { |
spinlock_unlock(&zones.lock); |
if (pzone) |
*pzone = i; |
return z; |
} |
i++; |
if (i >= zones.count) |
spinlock_unlock(&z->lock); |
if (++i >= zones.count) |
i = 0; |
} while (i != hint); |
return (count_t) -1; |
} while(i != hint); |
spinlock_unlock(&zones.lock); |
return NULL; |
} |
/**************************/ |
250,146 → 283,167 |
/* Buddy system functions */ |
/**************************/ |
/** Buddy system find_block implementation. |
/** Buddy system find_block implementation |
* |
* Find block that is parent of current list. |
* That means go to lower addresses, until such block is found |
* |
* @param order Order of parent must be different then this |
* parameter!! |
* |
* @param order - Order of parent must be different then this parameter!! |
*/ |
static link_t *zone_buddy_find_block(buddy_system_t *buddy, link_t *child, |
static link_t *zone_buddy_find_block(buddy_system_t *b, link_t *child, |
uint8_t order) |
{ |
frame_t *frame = list_get_instance(child, frame_t, buddy_link); |
zone_t *zone = (zone_t *) buddy->data; |
frame_t *frame; |
zone_t *zone; |
index_t index; |
index_t index = frame_index(zone, frame); |
frame = list_get_instance(child, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
index = frame_index(zone, frame); |
do { |
if (zone->frames[index].buddy_order != order) |
if (zone->frames[index].buddy_order != order) { |
return &zone->frames[index].buddy_link; |
} while (index-- > 0); |
} |
} while(index-- > 0); |
return NULL; |
} |
/** Buddy system find_buddy implementation. |
static void zone_buddy_print_id(buddy_system_t *b, link_t *block) |
{ |
frame_t *frame; |
zone_t *zone; |
index_t index; |
frame = list_get_instance(block, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
index = frame_index(zone, frame); |
printf("%zd", index); |
} |
/** Buddy system find_buddy implementation |
* |
* @param buddy Buddy system. |
* @param block Block for which buddy should be found. |
* @param b Buddy system. |
* @param block Block for which buddy should be found |
* |
* @return Buddy for given block if found. |
* |
* @return Buddy for given block if found |
*/ |
static link_t *zone_buddy_find_buddy(buddy_system_t *buddy, link_t *block) |
static link_t *zone_buddy_find_buddy(buddy_system_t *b, link_t *block) |
{ |
frame_t *frame = list_get_instance(block, frame_t, buddy_link); |
zone_t *zone = (zone_t *) buddy->data; |
frame_t *frame; |
zone_t *zone; |
index_t index; |
bool is_left, is_right; |
frame = list_get_instance(block, frame_t, buddy_link); |
zone = (zone_t *) b->data; |
ASSERT(IS_BUDDY_ORDER_OK(frame_index_abs(zone, frame), |
frame->buddy_order)); |
bool is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
index_t index; |
is_left = IS_BUDDY_LEFT_BLOCK_ABS(zone, frame); |
is_right = IS_BUDDY_RIGHT_BLOCK_ABS(zone, frame); |
ASSERT(is_left ^ is_right); |
if (is_left) { |
index = (frame_index(zone, frame)) + |
(1 << frame->buddy_order); |
} else { /* is_right */ |
index = (frame_index(zone, frame)) - |
(1 << frame->buddy_order); |
index = (frame_index(zone, frame)) + (1 << frame->buddy_order); |
} else { /* if (is_right) */ |
index = (frame_index(zone, frame)) - (1 << frame->buddy_order); |
} |
if (frame_index_valid(zone, index)) { |
if ((zone->frames[index].buddy_order == frame->buddy_order) && |
(zone->frames[index].refcount == 0)) { |
if (zone->frames[index].buddy_order == frame->buddy_order && |
zone->frames[index].refcount == 0) { |
return &zone->frames[index].buddy_link; |
} |
} |
return NULL; |
return NULL; |
} |
/** Buddy system bisect implementation. |
/** Buddy system bisect implementation |
* |
* @param buddy Buddy system. |
* @param block Block to bisect. |
* @param b Buddy system. |
* @param block Block to bisect |
* |
* @return Right block. |
* |
* @return right block |
*/ |
static link_t *zone_buddy_bisect(buddy_system_t *buddy, link_t *block) |
{ |
frame_t *frame_l = list_get_instance(block, frame_t, buddy_link); |
frame_t *frame_r = (frame_l + (1 << (frame_l->buddy_order - 1))); |
static link_t * zone_buddy_bisect(buddy_system_t *b, link_t *block) { |
frame_t *frame_l, *frame_r; |
frame_l = list_get_instance(block, frame_t, buddy_link); |
frame_r = (frame_l + (1 << (frame_l->buddy_order - 1))); |
return &frame_r->buddy_link; |
} |
/** Buddy system coalesce implementation. |
/** Buddy system coalesce implementation |
* |
* @param buddy Buddy system. |
* @param block_1 First block. |
* @param block_2 First block's buddy. |
* @param b Buddy system. |
* @param block_1 First block |
* @param block_2 First block's buddy |
* |
* @return Coalesced block (actually block that represents lower |
* address). |
* |
* @return Coalesced block (actually block that represents lower address) |
*/ |
static link_t *zone_buddy_coalesce(buddy_system_t *buddy, link_t *block_1, |
link_t *block_2) |
static link_t *zone_buddy_coalesce(buddy_system_t *b, link_t *block_1, |
link_t *block_2) |
{ |
frame_t *frame1 = list_get_instance(block_1, frame_t, buddy_link); |
frame_t *frame2 = list_get_instance(block_2, frame_t, buddy_link); |
frame_t *frame1, *frame2; |
return ((frame1 < frame2) ? block_1 : block_2); |
frame1 = list_get_instance(block_1, frame_t, buddy_link); |
frame2 = list_get_instance(block_2, frame_t, buddy_link); |
return frame1 < frame2 ? block_1 : block_2; |
} |
/** Buddy system set_order implementation. |
/** Buddy system set_order implementation |
* |
* @param buddy Buddy system. |
* @param block Buddy system block. |
* @param order Order to set. |
* |
* @param b Buddy system. |
* @param block Buddy system block |
* @param order Order to set |
*/ |
static void zone_buddy_set_order(buddy_system_t *buddy, link_t *block, |
uint8_t order) |
{ |
list_get_instance(block, frame_t, buddy_link)->buddy_order = order; |
static void zone_buddy_set_order(buddy_system_t *b, link_t *block, |
uint8_t order) { |
frame_t *frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->buddy_order = order; |
} |
/** Buddy system get_order implementation. |
/** Buddy system get_order implementation |
* |
* @param buddy Buddy system. |
* @param block Buddy system block. |
* @param b Buddy system. |
* @param block Buddy system block |
* |
* @return Order of block. |
* |
* @return Order of block |
*/ |
static uint8_t zone_buddy_get_order(buddy_system_t *buddy, link_t *block) |
{ |
return list_get_instance(block, frame_t, buddy_link)->buddy_order; |
static uint8_t zone_buddy_get_order(buddy_system_t *b, link_t *block) { |
frame_t *frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
return frame->buddy_order; |
} |
/** Buddy system mark_busy implementation. |
/** Buddy system mark_busy implementation |
* |
* @param buddy Buddy system. |
* @param block Buddy system block. |
* @param b Buddy system |
* @param block Buddy system block |
* |
*/ |
static void zone_buddy_mark_busy(buddy_system_t *buddy, link_t * block) |
{ |
list_get_instance(block, frame_t, buddy_link)->refcount = 1; |
static void zone_buddy_mark_busy(buddy_system_t *b, link_t * block) { |
frame_t * frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->refcount = 1; |
} |
/** Buddy system mark_available implementation. |
/** Buddy system mark_available implementation |
* |
* @param buddy Buddy system. |
* @param block Buddy system block. |
* @param b Buddy system |
* @param block Buddy system block |
* |
*/ |
static void zone_buddy_mark_available(buddy_system_t *buddy, link_t *block) |
{ |
list_get_instance(block, frame_t, buddy_link)->refcount = 0; |
static void zone_buddy_mark_available(buddy_system_t *b, link_t *block) { |
frame_t *frame; |
frame = list_get_instance(block, frame_t, buddy_link); |
frame->refcount = 0; |
} |
static buddy_system_operations_t zone_buddy_system_operations = { |
400,7 → 454,8 |
.get_order = zone_buddy_get_order, |
.mark_busy = zone_buddy_mark_busy, |
.mark_available = zone_buddy_mark_available, |
.find_block = zone_buddy_find_block |
.find_block = zone_buddy_find_block, |
.print_id = zone_buddy_print_id |
}; |
/******************/ |
407,59 → 462,62 |
/* Zone functions */ |
/******************/ |
/** Allocate frame in particular zone. |
/** Allocate frame in particular zone |
* |
* Assume zone is locked and is available for allocation. |
* Assume zone is locked |
* Panics if allocation is impossible. |
* |
* @param zone Zone to allocate from. |
* @param order Allocate exactly 2^order frames. |
* |
* @return Frame index in zone. |
* @return Frame index in zone |
* |
*/ |
static pfn_t zone_frame_alloc(zone_t *zone, uint8_t order) |
{ |
ASSERT(zone_flags_available(zone->flags)); |
pfn_t v; |
link_t *tmp; |
frame_t *frame; |
/* Allocate frames from zone buddy system */ |
link_t *link = buddy_system_alloc(zone->buddy_system, order); |
tmp = buddy_system_alloc(zone->buddy_system, order); |
ASSERT(link); |
ASSERT(tmp); |
/* Update zone information. */ |
zone->free_count -= (1 << order); |
zone->busy_count += (1 << order); |
/* Frame will be actually a first frame of the block. */ |
frame_t *frame = list_get_instance(link, frame_t, buddy_link); |
frame = list_get_instance(tmp, frame_t, buddy_link); |
/* Get frame address */ |
return make_frame_index(zone, frame); |
/* get frame address */ |
v = make_frame_index(zone, frame); |
return v; |
} |
/** Free frame from zone. |
/** Free frame from zone |
* |
* Assume zone is locked and is available for deallocation. |
* Assume zone is locked |
* |
* @param zone Pointer to zone from which the frame is to be freed. |
* @param frame_idx Frame index relative to zone. |
* |
* @param zone Pointer to zone from which the frame is to be freed |
* @param frame_idx Frame index relative to zone |
*/ |
static void zone_frame_free(zone_t *zone, index_t frame_idx) |
{ |
ASSERT(zone_flags_available(zone->flags)); |
frame_t *frame; |
uint8_t order; |
frame = &zone->frames[frame_idx]; |
frame_t *frame = &zone->frames[frame_idx]; |
/* Remember frame order */ |
uint8_t order = frame->buddy_order; |
/* remember frame order */ |
order = frame->buddy_order; |
ASSERT(frame->refcount); |
if (!--frame->refcount) { |
buddy_system_free(zone->buddy_system, &frame->buddy_link); |
/* Update zone information. */ |
zone->free_count += (1 << order); |
zone->busy_count -= (1 << order); |
466,643 → 524,521 |
} |
} |
/** Return frame from zone. */ |
static frame_t *zone_get_frame(zone_t *zone, index_t frame_idx) |
/** Return frame from zone */ |
static frame_t * zone_get_frame(zone_t *zone, index_t frame_idx) |
{ |
ASSERT(frame_idx < zone->count); |
return &zone->frames[frame_idx]; |
} |
/** Mark frame in zone unavailable to allocation. */ |
/** Mark frame in zone unavailable to allocation */ |
static void zone_mark_unavailable(zone_t *zone, index_t frame_idx) |
{ |
ASSERT(zone_flags_available(zone->flags)); |
frame_t *frame = zone_get_frame(zone, frame_idx); |
frame_t *frame; |
link_t *link; |
frame = zone_get_frame(zone, frame_idx); |
if (frame->refcount) |
return; |
link_t *link __attribute__ ((unused)); |
link = buddy_system_alloc_block(zone->buddy_system, |
&frame->buddy_link); |
ASSERT(link); |
zone->free_count--; |
} |
/** Merge two zones. |
/** |
* Join 2 zones |
* |
* Expect buddy to point to space at least zone_conf_size large. |
* Assume z1 & z2 are locked and compatible and zones lock is |
* locked. |
* Expect zone_t *z to point to space at least zone_conf_size large |
* |
* @param z1 First zone to merge. |
* @param z2 Second zone to merge. |
* @param old_z1 Original date of the first zone. |
* @param buddy Merged zone buddy. |
* Assume z1 & z2 are locked |
* |
* @param z Target zone structure pointer |
* @param z1 Zone to merge |
* @param z2 Zone to merge |
*/ |
static void zone_merge_internal(count_t z1, count_t z2, zone_t *old_z1, buddy_system_t *buddy) |
static void _zone_merge(zone_t *z, zone_t *z1, zone_t *z2) |
{ |
ASSERT(zone_flags_available(zones.info[z1].flags)); |
ASSERT(zone_flags_available(zones.info[z2].flags)); |
ASSERT(zones.info[z1].flags == zones.info[z2].flags); |
ASSERT(zones.info[z1].base < zones.info[z2].base); |
ASSERT(!overlaps(zones.info[z1].base, zones.info[z1].count, |
zones.info[z2].base, zones.info[z2].count)); |
uint8_t max_order; |
unsigned int i; |
int z2idx; |
pfn_t frame_idx; |
frame_t *frame; |
ASSERT(!overlaps(z1->base, z1->count, z2->base, z2->count)); |
ASSERT(z1->base < z2->base); |
spinlock_initialize(&z->lock, "zone_lock"); |
z->base = z1->base; |
z->count = z2->base + z2->count - z1->base; |
z->flags = z1->flags & z2->flags; |
z->free_count = z1->free_count + z2->free_count; |
z->busy_count = z1->busy_count + z2->busy_count; |
/* Difference between zone bases */ |
pfn_t base_diff = zones.info[z2].base - zones.info[z1].base; |
zones.info[z1].count = base_diff + zones.info[z2].count; |
zones.info[z1].free_count += zones.info[z2].free_count; |
zones.info[z1].busy_count += zones.info[z2].busy_count; |
zones.info[z1].buddy_system = buddy; |
uint8_t order = fnzb(zones.info[z1].count); |
buddy_system_create(zones.info[z1].buddy_system, order, |
&zone_buddy_system_operations, (void *) &zones.info[z1]); |
zones.info[z1].frames = |
(frame_t *) ((uint8_t *) zones.info[z1].buddy_system |
+ buddy_conf_size(order)); |
/* This marks all frames busy */ |
count_t i; |
for (i = 0; i < zones.info[z1].count; i++) |
frame_initialize(&zones.info[z1].frames[i]); |
max_order = fnzb(z->count); |
z->buddy_system = (buddy_system_t *) &z[1]; |
buddy_system_create(z->buddy_system, max_order, |
&zone_buddy_system_operations, (void *) z); |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + |
buddy_conf_size(max_order)); |
for (i = 0; i < z->count; i++) { |
/* This marks all frames busy */ |
frame_initialize(&z->frames[i]); |
} |
/* Copy frames from both zones to preserve full frame orders, |
* parents etc. Set all free frames with refcount = 0 to 1, because |
* we add all free frames to buddy allocator later again, clearing |
* order to 0. Don't set busy frames with refcount = 0, as they |
* parents etc. Set all free frames with refcount=0 to 1, because |
* we add all free frames to buddy allocator later again, clear |
* order to 0. Don't set busy frames with refcount=0, as they |
* will not be reallocated during merge and it would make later |
* problems with allocation/free. |
*/ |
for (i = 0; i < old_z1->count; i++) |
zones.info[z1].frames[i] = old_z1->frames[i]; |
for (i = 0; i < zones.info[z2].count; i++) |
zones.info[z1].frames[base_diff + i] |
= zones.info[z2].frames[i]; |
for (i = 0; i < z1->count; i++) |
z->frames[i] = z1->frames[i]; |
for (i = 0; i < z2->count; i++) { |
z2idx = i + (z2->base - z1->base); |
z->frames[z2idx] = z2->frames[i]; |
} |
i = 0; |
while (i < zones.info[z1].count) { |
if (zones.info[z1].frames[i].refcount) { |
/* Skip busy frames */ |
i += 1 << zones.info[z1].frames[i].buddy_order; |
} else { |
/* Free frames, set refcount = 1 |
* (all free frames have refcount == 0, we need not |
* to check the order) |
*/ |
zones.info[z1].frames[i].refcount = 1; |
zones.info[z1].frames[i].buddy_order = 0; |
while (i < z->count) { |
if (z->frames[i].refcount) { |
/* skip busy frames */ |
i += 1 << z->frames[i].buddy_order; |
} else { /* Free frames, set refcount=1 */ |
/* All free frames have refcount=0, we need not |
* to check the order */ |
z->frames[i].refcount = 1; |
z->frames[i].buddy_order = 0; |
i++; |
} |
} |
/* Add free blocks from the original zone z1 */ |
while (zone_can_alloc(old_z1, 0)) { |
/* Allocate from the original zone */ |
pfn_t frame_idx = zone_frame_alloc(old_z1, 0); |
/* Free the frame from the merged zone */ |
frame_t *frame = &zones.info[z1].frames[frame_idx]; |
/* Add free blocks from the 2 original zones */ |
while (zone_can_alloc(z1, 0)) { |
frame_idx = zone_frame_alloc(z1, 0); |
frame = &z->frames[frame_idx]; |
frame->refcount = 0; |
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link); |
buddy_system_free(z->buddy_system, &frame->buddy_link); |
} |
/* Add free blocks from the original zone z2 */ |
while (zone_can_alloc(&zones.info[z2], 0)) { |
/* Allocate from the original zone */ |
pfn_t frame_idx = zone_frame_alloc(&zones.info[z2], 0); |
/* Free the frame from the merged zone */ |
frame_t *frame = &zones.info[z1].frames[base_diff + frame_idx]; |
while (zone_can_alloc(z2, 0)) { |
frame_idx = zone_frame_alloc(z2, 0); |
frame = &z->frames[frame_idx + (z2->base - z1->base)]; |
frame->refcount = 0; |
buddy_system_free(zones.info[z1].buddy_system, &frame->buddy_link); |
buddy_system_free(z->buddy_system, &frame->buddy_link); |
} |
} |
/** Return old configuration frames into the zone. |
/** Return old configuration frames into the zone |
* |
* We have two cases: |
* - The configuration data is outside the zone |
* -> do nothing (perhaps call frame_free?) |
* - The configuration data was created by zone_create |
* or updated by reduce_region -> free every frame |
* We have several cases |
* - the conf. data is outside of zone -> exit, shall we call frame_free?? |
* - the conf. data was created by zone_create or |
* updated with reduce_region -> free every frame |
* |
* @param znum The actual zone where freeing should occur. |
* @param pfn Old zone configuration frame. |
* @param count Old zone frame count. |
* |
* @param newzone The actual zone where freeing should occur |
* @param oldzone Pointer to old zone configuration data that should |
* be freed from new zone |
*/ |
static void return_config_frames(count_t znum, pfn_t pfn, count_t count) |
static void return_config_frames(zone_t *newzone, zone_t *oldzone) |
{ |
ASSERT(zone_flags_available(zones.info[znum].flags)); |
pfn_t pfn; |
frame_t *frame; |
count_t cframes; |
unsigned int i; |
pfn = ADDR2PFN((uintptr_t)KA2PA(oldzone)); |
cframes = SIZE2FRAMES(zone_conf_size(oldzone->count)); |
count_t cframes = SIZE2FRAMES(zone_conf_size(count)); |
if ((pfn < zones.info[znum].base) |
|| (pfn >= zones.info[znum].base + zones.info[znum].count)) |
if (pfn < newzone->base || pfn >= newzone->base + newzone->count) |
return; |
frame_t *frame __attribute__ ((unused)); |
frame = &zones.info[znum].frames[pfn - zones.info[znum].base]; |
frame = &newzone->frames[pfn - newzone->base]; |
ASSERT(!frame->buddy_order); |
count_t i; |
for (i = 0; i < cframes; i++) { |
zones.info[znum].busy_count++; |
zone_frame_free(&zones.info[znum], |
pfn - zones.info[znum].base + i); |
newzone->busy_count++; |
zone_frame_free(newzone, pfn+i-newzone->base); |
} |
} |
/** Reduce allocated block to count of order 0 frames. |
/** Reduce allocated block to count of order 0 frames |
* |
* The allocated block needs 2^order frames. Reduce all frames |
* in the block to order 0 and free the unneeded frames. This means that |
* when freeing the previously allocated block starting with frame_idx, |
* The allocated block need 2^order frames of space. Reduce all frames |
* in block to order 0 and free the unneeded frames. This means, that |
* when freeing the previously allocated block starting with frame_idx, |
* you have to free every frame. |
* |
* @param znum Zone. |
* @param frame_idx Index the first frame of the block. |
* @param count Allocated frames in block. |
* |
* @param zone |
* @param frame_idx Index to block |
* @param count Allocated space in block |
*/ |
static void zone_reduce_region(count_t znum, pfn_t frame_idx, count_t count) |
static void zone_reduce_region(zone_t *zone, pfn_t frame_idx, count_t count) |
{ |
ASSERT(zone_flags_available(zones.info[znum].flags)); |
ASSERT(frame_idx + count < zones.info[znum].count); |
count_t i; |
uint8_t order; |
frame_t *frame; |
uint8_t order = zones.info[znum].frames[frame_idx].buddy_order; |
ASSERT(frame_idx + count < zone->count); |
order = zone->frames[frame_idx].buddy_order; |
ASSERT((count_t) (1 << order) >= count); |
/* Reduce all blocks to order 0 */ |
count_t i; |
for (i = 0; i < (count_t) (1 << order); i++) { |
frame_t *frame = &zones.info[znum].frames[i + frame_idx]; |
frame = &zone->frames[i + frame_idx]; |
frame->buddy_order = 0; |
if (!frame->refcount) |
frame->refcount = 1; |
ASSERT(frame->refcount == 1); |
} |
/* Free unneeded frames */ |
for (i = count; i < (count_t) (1 << order); i++) |
zone_frame_free(&zones.info[znum], i + frame_idx); |
for (i = count; i < (count_t) (1 << order); i++) { |
zone_frame_free(zone, i + frame_idx); |
} |
} |
/** Merge zones z1 and z2. |
/** Merge zones z1 and z2 |
* |
* The merged zones must be 2 zones with no zone existing in between |
* (which means that z2 = z1 + 1). Both zones must be available zones |
* with the same flags. |
* - the zones must be 2 zones with no zone existing in between, |
* which means that z2 = z1+1 |
* |
* When you create a new zone, the frame allocator configuration does |
* not to be 2^order size. Once the allocator is running it is no longer |
* possible, merged configuration data occupies more space :-/ |
* |
* The function uses |
* |
* - When you create a new zone, the frame allocator configuration does |
* not to be 2^order size. Once the allocator is running it is no longer |
* possible, merged configuration data occupies more space :-/ |
*/ |
bool zone_merge(count_t z1, count_t z2) |
void zone_merge(unsigned int z1, unsigned int z2) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
zone_t *zone1, *zone2, *newzone; |
unsigned int cframes; |
uint8_t order; |
unsigned int i; |
pfn_t pfn; |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
bool ret = true; |
/* We can join only 2 zones with none existing inbetween, |
* the zones have to be available and with the same |
* set of flags |
*/ |
if ((z1 >= zones.count) || (z2 >= zones.count) |
|| (z2 - z1 != 1) |
|| (!zone_flags_available(zones.info[z1].flags)) |
|| (!zone_flags_available(zones.info[z2].flags)) |
|| (zones.info[z1].flags != zones.info[z2].flags)) { |
ret = false; |
if ((z1 >= zones.count) || (z2 >= zones.count)) |
goto errout; |
} |
pfn_t cframes = SIZE2FRAMES(zone_conf_size( |
zones.info[z2].base - zones.info[z1].base |
+ zones.info[z2].count)); |
uint8_t order; |
/* We can join only 2 zones with none existing inbetween */ |
if (z2-z1 != 1) |
goto errout; |
zone1 = zones.info[z1]; |
zone2 = zones.info[z2]; |
spinlock_lock(&zone1->lock); |
spinlock_lock(&zone2->lock); |
cframes = SIZE2FRAMES(zone_conf_size(zone2->base + zone2->count - |
zone1->base)); |
if (cframes == 1) |
order = 0; |
else |
order = fnzb(cframes - 1) + 1; |
/* Allocate zonedata inside one of the zones */ |
if (zone_can_alloc(zone1, order)) |
pfn = zone1->base + zone_frame_alloc(zone1, order); |
else if (zone_can_alloc(zone2, order)) |
pfn = zone2->base + zone_frame_alloc(zone2, order); |
else |
order = fnzb(cframes - 1) + 1; |
/* Allocate merged zone data inside one of the zones */ |
pfn_t pfn; |
if (zone_can_alloc(&zones.info[z1], order)) { |
pfn = zones.info[z1].base + zone_frame_alloc(&zones.info[z1], order); |
} else if (zone_can_alloc(&zones.info[z2], order)) { |
pfn = zones.info[z2].base + zone_frame_alloc(&zones.info[z2], order); |
} else { |
ret = false; |
goto errout; |
} |
/* Preserve original data from z1 */ |
zone_t old_z1 = zones.info[z1]; |
old_z1.buddy_system->data = (void *) &old_z1; |
/* Do zone merging */ |
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(pfn)); |
zone_merge_internal(z1, z2, &old_z1, buddy); |
goto errout2; |
newzone = (zone_t *) PA2KA(PFN2ADDR(pfn)); |
_zone_merge(newzone, zone1, zone2); |
/* Free unneeded config frames */ |
zone_reduce_region(z1, pfn - zones.info[z1].base, cframes); |
zone_reduce_region(newzone, pfn - newzone->base, cframes); |
/* Subtract zone information from busy frames */ |
zones.info[z1].busy_count -= cframes; |
/* Free old zone information */ |
return_config_frames(z1, |
ADDR2PFN(KA2PA((uintptr_t) old_z1.frames)), old_z1.count); |
return_config_frames(z1, |
ADDR2PFN(KA2PA((uintptr_t) zones.info[z2].frames)), |
zones.info[z2].count); |
/* Move zones down */ |
count_t i; |
for (i = z2 + 1; i < zones.count; i++) { |
newzone->busy_count -= cframes; |
/* Replace existing zones in zoneinfo list */ |
zones.info[z1] = newzone; |
for (i = z2 + 1; i < zones.count; i++) |
zones.info[i - 1] = zones.info[i]; |
zones.info[i - 1].buddy_system->data = |
(void *) &zones.info[i - 1]; |
} |
zones.count--; |
/* Free old zone information */ |
return_config_frames(newzone, zone1); |
return_config_frames(newzone, zone2); |
errout2: |
/* Nobody is allowed to enter to zone, so we are safe |
* to touch the spinlocks last time */ |
spinlock_unlock(&zone1->lock); |
spinlock_unlock(&zone2->lock); |
errout: |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return ret; |
} |
/** Merge all mergeable zones into one big zone. |
/** |
* Merge all zones into one big zone |
* |
* It is reasonable to do this on systems where |
* BIOS reports parts in chunks, so that we could |
* have 1 zone (it's faster). |
* |
* It is reasonable to do this on systems whose bios reports parts in chunks, |
* so that we could have 1 zone (it's faster). |
*/ |
void zone_merge_all(void) |
{ |
count_t i = 0; |
while (i < zones.count) { |
if (!zone_merge(i, i + 1)) |
i++; |
int count = zones.count; |
while (zones.count > 1 && --count) { |
zone_merge(0,1); |
break; |
} |
} |
/** Create new frame zone. |
/** Create frame zone |
* |
* @param zone Zone to construct. |
* @param buddy Address of buddy system configuration information. |
* Create new frame zone. |
* |
* @param start Physical address of the first frame within the zone. |
* @param count Count of frames in zone. |
* @param count Count of frames in zone |
* @param z Address of configuration information of zone |
* @param flags Zone flags. |
* |
* @return Initialized zone. |
* |
*/ |
static void zone_construct(zone_t *zone, buddy_system_t *buddy, pfn_t start, count_t count, zone_flags_t flags) |
static void zone_construct(pfn_t start, count_t count, zone_t *z, int flags) |
{ |
zone->base = start; |
zone->count = count; |
zone->flags = flags; |
zone->free_count = count; |
zone->busy_count = 0; |
zone->buddy_system = buddy; |
unsigned int i; |
uint8_t max_order; |
spinlock_initialize(&z->lock, "zone_lock"); |
z->base = start; |
z->count = count; |
z->flags = flags; |
z->free_count = count; |
z->busy_count = 0; |
/* |
* Compute order for buddy system, initialize |
*/ |
max_order = fnzb(count); |
z->buddy_system = (buddy_system_t *)&z[1]; |
if (zone_flags_available(flags)) { |
/* |
* Compute order for buddy system and initialize |
*/ |
uint8_t order = fnzb(count); |
buddy_system_create(zone->buddy_system, order, |
&zone_buddy_system_operations, (void *) zone); |
/* Allocate frames _after_ the confframe */ |
/* Check sizes */ |
zone->frames = (frame_t *) ((uint8_t *) zone->buddy_system + |
buddy_conf_size(order)); |
count_t i; |
for (i = 0; i < count; i++) |
frame_initialize(&zone->frames[i]); |
/* Stuffing frames */ |
for (i = 0; i < count; i++) { |
zone->frames[i].refcount = 0; |
buddy_system_free(zone->buddy_system, &zone->frames[i].buddy_link); |
} |
} else |
zone->frames = NULL; |
buddy_system_create(z->buddy_system, max_order, |
&zone_buddy_system_operations, |
(void *) z); |
/* Allocate frames _after_ the conframe */ |
/* Check sizes */ |
z->frames = (frame_t *)((uint8_t *) z->buddy_system + |
buddy_conf_size(max_order)); |
for (i = 0; i < count; i++) { |
frame_initialize(&z->frames[i]); |
} |
/* Stuffing frames */ |
for (i = 0; i < count; i++) { |
z->frames[i].refcount = 0; |
buddy_system_free(z->buddy_system, &z->frames[i].buddy_link); |
} |
} |
/** Compute configuration data size for zone. |
/** Compute configuration data size for zone |
* |
* @param count Size of zone in frames. |
* |
* @return Size of zone configuration info (in bytes). |
* |
* @param count Size of zone in frames |
* @return Size of zone configuration info (in bytes) |
*/ |
uintptr_t zone_conf_size(count_t count) |
{ |
return (count * sizeof(frame_t) + buddy_conf_size(fnzb(count))); |
int size = sizeof(zone_t) + count*sizeof(frame_t); |
int max_order; |
max_order = fnzb(count); |
size += buddy_conf_size(max_order); |
return size; |
} |
/** Create and add zone to system. |
/** Create and add zone to system |
* |
* @param start First frame number (absolute). |
* @param count Size of zone in frames. |
* @param start First frame number (absolute) |
* @param count Size of zone in frames |
* @param confframe Where configuration frames are supposed to be. |
* Automatically checks, that we will not disturb the |
* kernel and possibly init. If confframe is given |
* _outside_ this zone, it is expected, that the area is |
* already marked BUSY and big enough to contain |
* zone_conf_size() amount of data. If the confframe is |
* inside the area, the zone free frame information is |
* modified not to include it. |
* Automatically checks, that we will not disturb the |
* kernel and possibly init. |
* If confframe is given _outside_ this zone, it is expected, |
* that the area is already marked BUSY and big enough |
* to contain zone_conf_size() amount of data. |
* If the confframe is inside the area, the zone free frame |
* information is modified not to include it. |
* |
* @return Zone number or -1 on error. |
* |
* @return Zone number or -1 on error |
*/ |
count_t zone_create(pfn_t start, count_t count, pfn_t confframe, zone_flags_t flags) |
int zone_create(pfn_t start, count_t count, pfn_t confframe, int flags) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
if (zone_flags_available(flags)) { /* Create available zone */ |
/* Theoretically we could have NULL here, practically make sure |
* nobody tries to do that. If some platform requires, remove |
* the assert |
*/ |
ASSERT(confframe != NULL); |
/* If confframe is supposed to be inside our zone, then make sure |
* it does not span kernel & init |
*/ |
count_t confcount = SIZE2FRAMES(zone_conf_size(count)); |
if ((confframe >= start) && (confframe < start + count)) { |
for (; confframe < start + count; confframe++) { |
uintptr_t addr = PFN2ADDR(confframe); |
zone_t *z; |
uintptr_t addr; |
count_t confcount; |
unsigned int i; |
int znum; |
/* Theoretically we could have here 0, practically make sure |
* nobody tries to do that. If some platform requires, remove |
* the assert |
*/ |
ASSERT(confframe); |
/* If conframe is supposed to be inside our zone, then make sure |
* it does not span kernel & init |
*/ |
confcount = SIZE2FRAMES(zone_conf_size(count)); |
if (confframe >= start && confframe < start+count) { |
for (;confframe < start + count; confframe++) { |
addr = PFN2ADDR(confframe); |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.base), config.kernel_size)) |
continue; |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.stack_base), config.stack_size)) |
continue; |
bool overlap = false; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.base), config.kernel_size)) |
continue; |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(config.stack_base), config.stack_size)) |
continue; |
bool overlap = false; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(addr, PFN2ADDR(confcount), |
KA2PA(init.tasks[i].addr), |
init.tasks[i].size)) { |
overlap = true; |
break; |
} |
if (overlap) |
continue; |
break; |
} |
KA2PA(init.tasks[i].addr), |
init.tasks[i].size)) { |
overlap = true; |
break; |
} |
if (overlap) |
continue; |
if (confframe >= start + count) |
panic("Cannot find configuration data for zone."); |
break; |
} |
count_t znum = zones_insert_zone(start, count); |
if (znum == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return (count_t) -1; |
if (confframe >= start + count) |
panic("Cannot find configuration data for zone."); |
} |
z = (zone_t *) PA2KA(PFN2ADDR(confframe)); |
zone_construct(start, count, z, flags); |
znum = zones_add_zone(z); |
if (znum == -1) |
return -1; |
/* If confdata in zone, mark as unavailable */ |
if (confframe >= start && confframe < start + count) |
for (i = confframe; i < confframe + confcount; i++) { |
zone_mark_unavailable(z, i - z->base); |
} |
buddy_system_t *buddy = (buddy_system_t *) PA2KA(PFN2ADDR(confframe)); |
zone_construct(&zones.info[znum], buddy, start, count, flags); |
/* If confdata in zone, mark as unavailable */ |
if ((confframe >= start) && (confframe < start + count)) { |
count_t i; |
for (i = confframe; i < confframe + confcount; i++) |
zone_mark_unavailable(&zones.info[znum], |
i - zones.info[znum].base); |
} |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return znum; |
} |
/* Non-available zone */ |
count_t znum = zones_insert_zone(start, count); |
if (znum == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return (count_t) -1; |
} |
zone_construct(&zones.info[znum], NULL, start, count, flags); |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return znum; |
} |
/*******************/ |
/***************************************/ |
/* Frame functions */ |
/*******************/ |
/** Set parent of frame. */ |
void frame_set_parent(pfn_t pfn, void *data, count_t hint) |
/** Set parent of frame */ |
void frame_set_parent(pfn_t pfn, void *data, unsigned int hint) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_t) -1); |
zone_get_frame(&zones.info[znum], |
pfn - zones.info[znum].base)->parent = data; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
zone_t *zone = find_zone_and_lock(pfn, &hint); |
ASSERT(zone); |
zone_get_frame(zone, pfn-zone->base)->parent = data; |
spinlock_unlock(&zone->lock); |
} |
void *frame_get_parent(pfn_t pfn, count_t hint) |
void *frame_get_parent(pfn_t pfn, unsigned int hint) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
zone_t *zone = find_zone_and_lock(pfn, &hint); |
void *res; |
ASSERT(zone); |
res = zone_get_frame(zone, pfn - zone->base)->parent; |
count_t znum = find_zone(pfn, 1, hint); |
ASSERT(znum != (count_t) -1); |
void *res = zone_get_frame(&zones.info[znum], |
pfn - zones.info[znum].base)->parent; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
spinlock_unlock(&zone->lock); |
return res; |
} |
/** Allocate power-of-two frames of physical memory. |
* |
* @param order Allocate exactly 2^order frames. |
* @param flags Flags for host zone selection and address processing. |
* @param pzone Preferred zone. |
* @param order Allocate exactly 2^order frames. |
* @param flags Flags for host zone selection and address processing. |
* @param pzone Preferred zone |
* |
* @return Physical address of the allocated frame. |
* |
*/ |
void *frame_alloc_generic(uint8_t order, frame_flags_t flags, count_t *pzone) |
void * frame_alloc_generic(uint8_t order, int flags, unsigned int *pzone) |
{ |
count_t size = ((count_t) 1) << order; |
ipl_t ipl; |
count_t hint = pzone ? (*pzone) : 0; |
int freed; |
pfn_t v; |
zone_t *zone; |
loop: |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
/* |
* First, find suitable frame zone. |
*/ |
count_t znum = find_free_zone(order, |
FRAME_TO_ZONE_FLAGS(flags), hint); |
zone = find_free_zone_and_lock(order, pzone); |
/* If no memory, reclaim some slab memory, |
if it does not help, reclaim all */ |
if ((znum == (count_t) -1) && (!(flags & FRAME_NO_RECLAIM))) { |
count_t freed = slab_reclaim(0); |
if (freed > 0) |
znum = find_free_zone(order, |
FRAME_TO_ZONE_FLAGS(flags), hint); |
if (znum == (count_t) -1) { |
if (!zone && !(flags & FRAME_NO_RECLAIM)) { |
freed = slab_reclaim(0); |
if (freed) |
zone = find_free_zone_and_lock(order, pzone); |
if (!zone) { |
freed = slab_reclaim(SLAB_RECLAIM_ALL); |
if (freed > 0) |
znum = find_free_zone(order, |
FRAME_TO_ZONE_FLAGS(flags), hint); |
if (freed) |
zone = find_free_zone_and_lock(order, pzone); |
} |
} |
if (znum == (count_t) -1) { |
if (flags & FRAME_ATOMIC) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return NULL; |
} |
#ifdef CONFIG_DEBUG |
count_t avail = total_frames_free(); |
#endif |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
if (!zone) { |
/* |
* Sleep until some frames are available again. |
* TODO: Sleep until frames are available again. |
*/ |
interrupts_restore(ipl); |
if (flags & FRAME_ATOMIC) |
return 0; |
#ifdef CONFIG_DEBUG |
printf("Thread %" PRIu64 " waiting for %" PRIc " frames, " |
"%" PRIc " available.\n", THREAD->tid, size, avail); |
#endif |
mutex_lock(&mem_avail_mtx); |
if (mem_avail_req > 0) |
mem_avail_req = min(mem_avail_req, size); |
else |
mem_avail_req = size; |
count_t gen = mem_avail_gen; |
while (gen == mem_avail_gen) |
condvar_wait(&mem_avail_cv, &mem_avail_mtx); |
mutex_unlock(&mem_avail_mtx); |
#ifdef CONFIG_DEBUG |
printf("Thread %" PRIu64 " woken up.\n", THREAD->tid); |
#endif |
panic("Sleep not implemented.\n"); |
goto loop; |
} |
pfn_t pfn = zone_frame_alloc(&zones.info[znum], order) |
+ zones.info[znum].base; |
spinlock_unlock(&zones.lock); |
v = zone_frame_alloc(zone, order); |
v += zone->base; |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
if (pzone) |
*pzone = znum; |
if (flags & FRAME_KA) |
return (void *) PA2KA(PFN2ADDR(pfn)); |
return (void *) PFN2ADDR(pfn); |
return (void *)PA2KA(PFN2ADDR(v)); |
return (void *)PFN2ADDR(v); |
} |
/** Free a frame. |
* |
* Find respective frame structure for supplied physical frame address. |
* Decrement frame reference count. If it drops to zero, move the frame |
* structure to free list. |
* Decrement frame reference count. |
* If it drops to zero, move the frame structure to free list. |
* |
* @param frame Physical Address of of the frame to be freed. |
* |
* @param Frame Physical Address of of the frame to be freed. |
*/ |
void frame_free(uintptr_t frame) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
ipl_t ipl; |
zone_t *zone; |
pfn_t pfn = ADDR2PFN(frame); |
ipl = interrupts_disable(); |
/* |
* First, find host frame zone for addr. |
*/ |
pfn_t pfn = ADDR2PFN(frame); |
count_t znum = find_zone(pfn, 1, NULL); |
zone = find_zone_and_lock(pfn,NULL); |
ASSERT(zone); |
ASSERT(znum != (count_t) -1); |
zone_frame_free(zone, pfn-zone->base); |
zone_frame_free(&zones.info[znum], pfn - zones.info[znum].base); |
spinlock_unlock(&zones.lock); |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
/* |
* Signal that some memory has been freed. |
*/ |
mutex_lock(&mem_avail_mtx); |
if (mem_avail_req > 0) |
mem_avail_req--; |
if (mem_avail_req == 0) { |
mem_avail_gen++; |
condvar_broadcast(&mem_avail_cv); |
} |
mutex_unlock(&mem_avail_mtx); |
} |
/** Add reference to frame. |
1111,56 → 1047,55 |
* increment frame reference count. |
* |
* @param pfn Frame number of the frame to be freed. |
* |
*/ |
void frame_reference_add(pfn_t pfn) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
ipl_t ipl; |
zone_t *zone; |
frame_t *frame; |
ipl = interrupts_disable(); |
/* |
* First, find host frame zone for addr. |
*/ |
count_t znum = find_zone(pfn, 1, NULL); |
zone = find_zone_and_lock(pfn,NULL); |
ASSERT(zone); |
ASSERT(znum != (count_t) -1); |
frame = &zone->frames[pfn-zone->base]; |
frame->refcount++; |
zones.info[znum].frames[pfn - zones.info[znum].base].refcount++; |
spinlock_unlock(&zones.lock); |
spinlock_unlock(&zone->lock); |
interrupts_restore(ipl); |
} |
/** Mark given range unavailable in frame zones. */ |
/** Mark given range unavailable in frame zones */ |
void frame_mark_unavailable(pfn_t start, count_t count) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
unsigned int i; |
zone_t *zone; |
unsigned int prefzone = 0; |
count_t i; |
for (i = 0; i < count; i++) { |
count_t znum = find_zone(start + i, 1, 0); |
if (znum == (count_t) -1) /* PFN not found */ |
zone = find_zone_and_lock(start + i, &prefzone); |
if (!zone) /* PFN not found */ |
continue; |
zone_mark_unavailable(&zones.info[znum], |
start + i - zones.info[znum].base); |
zone_mark_unavailable(zone, start + i - zone->base); |
spinlock_unlock(&zone->lock); |
} |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
/** Initialize physical memory management. */ |
/** Initialize physical memory management |
* |
* Initialize physical memory managemnt. |
*/ |
void frame_init(void) |
{ |
if (config.cpu_active == 1) { |
zones.count = 0; |
spinlock_initialize(&zones.lock, "zones.lock"); |
mutex_initialize(&mem_avail_mtx, MUTEX_ACTIVE); |
condvar_initialize(&mem_avail_cv); |
} |
/* Tell the architecture to create some memory */ |
frame_arch_init(); |
if (config.cpu_active == 1) { |
1175,28 → 1110,36 |
frame_mark_unavailable(pfn, |
SIZE2FRAMES(init.tasks[i].size)); |
} |
if (ballocs.size) |
frame_mark_unavailable(ADDR2PFN(KA2PA(ballocs.base)), |
SIZE2FRAMES(ballocs.size)); |
/* Black list first frame, as allocating NULL would |
* fail in some places |
*/ |
* fail in some places */ |
frame_mark_unavailable(0, 1); |
} |
} |
/** Return total size of all zones. */ |
uint64_t zone_total_size(void) |
{ |
ipl_t ipl = interrupts_disable(); |
/** Return total size of all zones |
* |
*/ |
uint64_t zone_total_size(void) { |
zone_t *zone = NULL; |
unsigned int i; |
ipl_t ipl; |
uint64_t total = 0; |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
uint64_t total = 0; |
count_t i; |
for (i = 0; i < zones.count; i++) |
total += (uint64_t) FRAMES2SIZE(zones.info[i].count); |
for (i = 0; i < zones.count; i++) { |
zone = zones.info[i]; |
spinlock_lock(&zone->lock); |
total += (uint64_t) FRAMES2SIZE(zone->count); |
spinlock_unlock(&zone->lock); |
} |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
1204,128 → 1147,86 |
return total; |
} |
/** Prints list of zones. */ |
void zone_print_list(void) |
{ |
#ifdef __32_BITS__ |
printf("# base address frames flags free frames busy frames\n"); |
printf("-- ------------ ------------ -------- ------------ ------------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# base address frames flags free frames busy frames\n"); |
printf("-- -------------------- ------------ -------- ------------ ------------\n"); |
#endif |
/** Prints list of zones |
* |
*/ |
void zone_print_list(void) { |
zone_t *zone = NULL; |
unsigned int i; |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
/* |
* Because printing may require allocation of memory, we may not hold |
* the frame allocator locks when printing zone statistics. Therefore, |
* we simply gather the statistics under the protection of the locks and |
* print the statistics when the locks have been released. |
* |
* When someone adds/removes zones while we are printing the statistics, |
* we may end up with inaccurate output (e.g. a zone being skipped from |
* the listing). |
*/ |
if (sizeof(void *) == 4) { |
printf("# base address free frames busy frames\n"); |
printf("-- ------------ ------------ ------------\n"); |
} else { |
printf("# base address free frames busy frames\n"); |
printf("-- -------------------- ------------ ------------\n"); |
} |
count_t i; |
for (i = 0;; i++) { |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
for (i = 0; i < zones.count; i++) { |
zone = zones.info[i]; |
spinlock_lock(&zone->lock); |
if (i >= zones.count) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
break; |
} |
if (sizeof(void *) == 4) |
printf("%-2d %#10zx %12zd %12zd\n", i, PFN2ADDR(zone->base), |
zone->free_count, zone->busy_count); |
else |
printf("%-2d %#18zx %12zd %12zd\n", i, PFN2ADDR(zone->base), |
zone->free_count, zone->busy_count); |
uintptr_t base = PFN2ADDR(zones.info[i].base); |
count_t count = zones.info[i].count; |
zone_flags_t flags = zones.info[i].flags; |
count_t free_count = zones.info[i].free_count; |
count_t busy_count = zones.info[i].busy_count; |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
bool available = zone_flags_available(flags); |
printf("%-2" PRIc, i); |
#ifdef __32_BITS__ |
printf(" %10p", base); |
#endif |
#ifdef __64_BITS__ |
printf(" %18p", base); |
#endif |
printf(" %12" PRIc " %c%c%c ", count, |
available ? 'A' : ' ', |
(flags & ZONE_RESERVED) ? 'R' : ' ', |
(flags & ZONE_FIRMWARE) ? 'F' : ' '); |
if (available) |
printf("%12" PRIc " %12" PRIc, |
free_count, busy_count); |
printf("\n"); |
spinlock_unlock(&zone->lock); |
} |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
} |
/** Prints zone details. |
* |
* @param num Zone base address or zone number. |
* |
*/ |
void zone_print_one(count_t num) |
{ |
ipl_t ipl = interrupts_disable(); |
void zone_print_one(unsigned int num) { |
zone_t *zone = NULL; |
ipl_t ipl; |
unsigned int i; |
ipl = interrupts_disable(); |
spinlock_lock(&zones.lock); |
count_t znum = (count_t) -1; |
count_t i; |
for (i = 0; i < zones.count; i++) { |
if ((i == num) || (PFN2ADDR(zones.info[i].base) == num)) { |
znum = i; |
if ((i == num) || (PFN2ADDR(zones.info[i]->base) == num)) { |
zone = zones.info[i]; |
break; |
} |
} |
if (znum == (count_t) -1) { |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
if (!zone) { |
printf("Zone not found.\n"); |
return; |
goto out; |
} |
uintptr_t base = PFN2ADDR(zones.info[i].base); |
zone_flags_t flags = zones.info[i].flags; |
count_t count = zones.info[i].count; |
count_t free_count = zones.info[i].free_count; |
count_t busy_count = zones.info[i].busy_count; |
spinlock_lock(&zone->lock); |
printf("Memory zone information\n"); |
printf("Zone base address: %#.*p\n", sizeof(uintptr_t) * 2, |
PFN2ADDR(zone->base)); |
printf("Zone size: %zd frames (%zd KB)\n", zone->count, |
SIZE2KB(FRAMES2SIZE(zone->count))); |
printf("Allocated space: %zd frames (%zd KB)\n", zone->busy_count, |
SIZE2KB(FRAMES2SIZE(zone->busy_count))); |
printf("Available space: %zd frames (%zd KB)\n", zone->free_count, |
SIZE2KB(FRAMES2SIZE(zone->free_count))); |
buddy_system_structure_print(zone->buddy_system, FRAME_SIZE); |
spinlock_unlock(&zone->lock); |
out: |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
bool available = zone_flags_available(flags); |
printf("Zone number: %" PRIc "\n", znum); |
printf("Zone base address: %p\n", base); |
printf("Zone size: %" PRIc " frames (%" PRIs " KiB)\n", count, |
SIZE2KB(FRAMES2SIZE(count))); |
printf("Zone flags: %c%c%c\n", |
available ? 'A' : ' ', |
(flags & ZONE_RESERVED) ? 'R' : ' ', |
(flags & ZONE_FIRMWARE) ? 'F' : ' '); |
if (available) { |
printf("Allocated space: %" PRIc " frames (%" PRIs " KiB)\n", |
busy_count, SIZE2KB(FRAMES2SIZE(busy_count))); |
printf("Available space: %" PRIc " frames (%" PRIs " KiB)\n", |
free_count, SIZE2KB(FRAMES2SIZE(free_count))); |
} |
} |
/** @} |
*/ |
/branches/dd/kernel/generic/src/mm/page.c |
---|
40,28 → 40,11 |
* They however, define the single interface. |
*/ |
/* |
* Note on memory prefetching and updating memory mappings, also described in: |
* AMD x86-64 Architecture Programmer's Manual, Volume 2, System Programming, |
* 7.2.1 Special Coherency Considerations. |
* |
* The processor which modifies a page table mapping can access prefetched data |
* from the old mapping. In order to prevent this, we place a memory barrier |
* after a mapping is updated. |
* |
* We assume that the other processors are either not using the mapping yet |
* (i.e. during the bootstrap) or are executing the TLB shootdown code. While |
* we don't care much about the former case, the processors in the latter case |
* will do an implicit serialization by virtue of running the TLB shootdown |
* interrupt handler. |
*/ |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <arch/mm/asid.h> |
#include <mm/as.h> |
#include <mm/frame.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
82,8 → 65,8 |
* considering possible crossings |
* of page boundaries. |
* |
* @param s Address of the structure. |
* @param size Size of the structure. |
* @param s Address of the structure. |
* @param size Size of the structure. |
*/ |
void map_structure(uintptr_t s, size_t size) |
{ |
93,11 → 76,8 |
cnt = length / PAGE_SIZE + (length % PAGE_SIZE > 0); |
for (i = 0; i < cnt; i++) |
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, |
s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, s + i * PAGE_SIZE, s + i * PAGE_SIZE, PAGE_NOT_CACHEABLE | PAGE_WRITE); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Insert mapping of page to frame. |
107,11 → 87,10 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be mapped. |
* @param frame Physical address of memory frame to which the mapping is |
* done. |
* @param flags Flags to be used for mapping. |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be mapped. |
* @param frame Physical address of memory frame to which the mapping is done. |
* @param flags Flags to be used for mapping. |
*/ |
void page_mapping_insert(as_t *as, uintptr_t page, uintptr_t frame, int flags) |
{ |
119,9 → 98,6 |
ASSERT(page_mapping_operations->mapping_insert); |
page_mapping_operations->mapping_insert(as, page, frame, flags); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Remove mapping of page. |
132,8 → 108,8 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be demapped. |
* @param as Address space to wich page belongs. |
* @param page Virtual address of the page to be demapped. |
*/ |
void page_mapping_remove(as_t *as, uintptr_t page) |
{ |
141,9 → 117,6 |
ASSERT(page_mapping_operations->mapping_remove); |
page_mapping_operations->mapping_remove(as, page); |
/* Repel prefetched accesses to the old mapping. */ |
memory_barrier(); |
} |
/** Find mapping for virtual page |
152,11 → 125,10 |
* |
* The page table must be locked and interrupts must be disabled. |
* |
* @param as Address space to wich page belongs. |
* @param page Virtual page. |
* @param as Address space to wich page belongs. |
* @param page Virtual page. |
* |
* @return NULL if there is no such mapping; requested mapping |
* otherwise. |
* @return NULL if there is no such mapping; requested mapping otherwise. |
*/ |
pte_t *page_mapping_find(as_t *as, uintptr_t page) |
{ |
/branches/dd/kernel/generic/src/mm/backend_phys.c |
---|
77,7 → 77,7 |
page_mapping_insert(AS, addr, base + (addr - area->base), |
as_area_get_flags(area)); |
if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1)) |
panic("Cannot insert used space."); |
panic("Could not insert used space.\n"); |
return AS_PF_OK; |
} |
/branches/dd/kernel/generic/src/mm/buddy.c |
---|
35,7 → 35,8 |
* @brief Buddy allocator framework. |
* |
* This file contains buddy system allocator framework. |
* Specialized functions are needed for this abstract framework to be useful. |
* Specialized functions are needed for this abstract framework |
* to be useful. |
*/ |
#include <mm/buddy.h> |
43,29 → 44,29 |
#include <arch/types.h> |
#include <debug.h> |
#include <print.h> |
#include <macros.h> |
/** Return size needed for the buddy configuration data. */ |
size_t buddy_conf_size(size_t max_order) |
/** Return size needed for the buddy configuration data */ |
size_t buddy_conf_size(int max_order) |
{ |
return sizeof(buddy_system_t) + (max_order + 1) * sizeof(link_t); |
} |
/** Create buddy system. |
/** Create buddy system |
* |
* Allocate memory for and initialize new buddy system. |
* |
* @param b Preallocated buddy system control data. |
* @param max_order The biggest allocable size will be 2^max_order. |
* @param op Operations for new buddy system. |
* @param data Pointer to be used by implementation. |
* @param b Preallocated buddy system control data. |
* @param max_order The biggest allocable size will be 2^max_order. |
* @param op Operations for new buddy system. |
* @param data Pointer to be used by implementation. |
* |
* @return New buddy system. |
* @return New buddy system. |
*/ |
void |
buddy_system_create(buddy_system_t *b, uint8_t max_order, |
buddy_system_operations_t *op, void *data) |
void buddy_system_create(buddy_system_t *b, |
uint8_t max_order, |
buddy_system_operations_t *op, |
void *data) |
{ |
int i; |
79,7 → 80,7 |
ASSERT(op->mark_busy); |
/* |
* Use memory after our own structure. |
* Use memory after our own structure |
*/ |
b->order = (link_t *) (&b[1]); |
91,15 → 92,14 |
b->data = data; |
} |
/** Check if buddy system can allocate block. |
/** Check if buddy system can allocate block |
* |
* @param b Buddy system pointer. |
* @param i Size of the block (2^i). |
* @param b Buddy system pointer |
* @param i Size of the block (2^i) |
* |
* @return True if block can be allocated. |
* @return True if block can be allocated |
*/ |
bool buddy_system_can_alloc(buddy_system_t *b, uint8_t i) |
{ |
bool buddy_system_can_alloc(buddy_system_t *b, uint8_t i) { |
uint8_t k; |
/* |
106,13 → 106,12 |
* If requested block is greater then maximal block |
* we know immediatly that we cannot satisfy the request. |
*/ |
if (i > b->max_order) |
return false; |
if (i > b->max_order) return false; |
/* |
* Check if any bigger or equal order has free elements |
*/ |
for (k = i; k <= b->max_order; k++) { |
for (k=i; k <= b->max_order; k++) { |
if (!list_empty(&b->order[k])) { |
return true; |
} |
119,11 → 118,12 |
} |
return false; |
} |
/** Allocate PARTICULAR block from buddy system. |
/** Allocate PARTICULAR block from buddy system |
* |
* @return Block of data or NULL if no such block was found. |
* @ return Block of data or NULL if no such block was found |
*/ |
link_t *buddy_system_alloc_block(buddy_system_t *b, link_t *block) |
{ |
134,7 → 134,7 |
ASSERT(left); |
list_remove(left); |
while (1) { |
if (!b->op->get_order(b, left)) { |
if (! b->op->get_order(b,left)) { |
b->op->mark_busy(b, left); |
return left; |
} |
142,8 → 142,8 |
order = b->op->get_order(b, left); |
right = b->op->bisect(b, left); |
b->op->set_order(b, left, order - 1); |
b->op->set_order(b, right, order - 1); |
b->op->set_order(b, left, order-1); |
b->op->set_order(b, right, order-1); |
tmp = b->op->find_block(b, block, BUDDY_SYSTEM_INNER_BLOCK); |
160,10 → 160,10 |
/** Allocate block from buddy system. |
* |
* @param b Buddy system pointer. |
* @param i Returned block will be 2^i big. |
* @param b Buddy system pointer. |
* @param i Returned block will be 2^i big. |
* |
* @return Block of data represented by link_t. |
* @return Block of data represented by link_t. |
*/ |
link_t *buddy_system_alloc(buddy_system_t *b, uint8_t i) |
{ |
217,12 → 217,13 |
buddy_system_free(b, hlp); |
return res; |
} |
/** Return block to buddy system. |
* |
* @param b Buddy system pointer. |
* @param block Block to return. |
* @param b Buddy system pointer. |
* @param block Block to return. |
*/ |
void buddy_system_free(buddy_system_t *b, link_t *block) |
{ |
266,8 → 267,7 |
b->op->set_order(b, hlp, i + 1); |
/* |
* Recursively add the coalesced block to the list of |
* order i + 1. |
* Recursively add the coalesced block to the list of order i + 1. |
*/ |
buddy_system_free(b, hlp); |
return; |
278,7 → 278,46 |
* Insert block into the list of order i. |
*/ |
list_append(block, &b->order[i]); |
} |
/** Prints out structure of buddy system |
* |
* @param b Pointer to buddy system |
* @param elem_size Element size |
*/ |
void buddy_system_structure_print(buddy_system_t *b, size_t elem_size) { |
index_t i; |
count_t cnt, elem_count = 0, block_count = 0; |
link_t * cur; |
printf("Order\tBlocks\tSize \tBlock size\tElems per block\n"); |
printf("-----\t------\t--------\t----------\t---------------\n"); |
for (i=0;i <= b->max_order; i++) { |
cnt = 0; |
if (!list_empty(&b->order[i])) { |
for (cur = b->order[i].next; cur != &b->order[i]; cur = cur->next) |
cnt++; |
} |
printf("#%zd\t%5zd\t%7zdK\t%8zdK\t%6zd\t", i, cnt, (cnt * (1 << i) * elem_size) >> 10, ((1 << i) * elem_size) >> 10, 1 << i); |
if (!list_empty(&b->order[i])) { |
for (cur = b->order[i].next; cur != &b->order[i]; cur = cur->next) { |
b->op->print_id(b, cur); |
printf(" "); |
} |
} |
printf("\n"); |
block_count += cnt; |
elem_count += (1 << i) * cnt; |
} |
printf("-----\t------\t--------\t----------\t---------------\n"); |
printf("Buddy system contains %zd free elements (%zd blocks)\n" , elem_count, block_count); |
} |
/** @} |
*/ |
/branches/dd/kernel/generic/src/synch/smc.c |
---|
File deleted |
/branches/dd/kernel/generic/src/synch/futex.c |
---|
115,7 → 115,6 |
uintptr_t paddr; |
pte_t *t; |
ipl_t ipl; |
int rc; |
ipl = interrupts_disable(); |
135,17 → 134,9 |
interrupts_restore(ipl); |
futex = futex_find(paddr); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_begin(); |
#endif |
rc = waitq_sleep_timeout(&futex->wq, usec, flags | |
return (unative_t) waitq_sleep_timeout(&futex->wq, usec, flags | |
SYNCH_FLAGS_INTERRUPTIBLE); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
return (unative_t) rc; |
} |
/** Wakeup one thread waiting in futex wait queue. |
/branches/dd/kernel/generic/src/synch/spinlock.c |
---|
106,8 → 106,9 |
continue; |
#endif |
if (i++ > DEADLOCK_THRESHOLD) { |
printf("cpu%u: looping on spinlock %" PRIp ":%s, caller=%" PRIp, |
CPU->id, sl, sl->name, CALLER); |
printf("cpu%d: looping on spinlock %.*p:%s, " |
"caller=%.*p", CPU->id, sizeof(uintptr_t) * 2, sl, |
sl->name, sizeof(uintptr_t) * 2, CALLER); |
symbol = get_symtab_entry(CALLER); |
if (symbol) |
printf("(%s)", symbol); |
118,7 → 119,7 |
} |
if (deadlock_reported) |
printf("cpu%u: not deadlocked\n", CPU->id); |
printf("cpu%d: not deadlocked\n", CPU->id); |
/* |
* Prevent critical section code from bleeding out this way up. |
/branches/dd/kernel/generic/src/synch/rwlock.c |
---|
82,7 → 82,7 |
*/ |
void rwlock_initialize(rwlock_t *rwl) { |
spinlock_initialize(&rwl->lock, "rwlock_t"); |
mutex_initialize(&rwl->exclusive, MUTEX_PASSIVE); |
mutex_initialize(&rwl->exclusive); |
rwl->readers_in = 0; |
} |
231,10 → 231,10 |
interrupts_restore(ipl); |
break; |
case ESYNCH_OK_ATOMIC: |
panic("_mutex_lock_timeout() == ESYNCH_OK_ATOMIC."); |
panic("_mutex_lock_timeout()==ESYNCH_OK_ATOMIC\n"); |
break; |
default: |
panic("Invalid ESYNCH."); |
panic("invalid ESYNCH\n"); |
break; |
} |
return rc; |
/branches/dd/kernel/generic/src/synch/condvar.c |
---|
43,7 → 43,7 |
/** Initialize condition variable. |
* |
* @param cv Condition variable. |
* @param cv Condition variable. |
*/ |
void condvar_initialize(condvar_t *cv) |
{ |
50,10 → 50,11 |
waitq_initialize(&cv->wq); |
} |
/** Signal the condition has become true to the first waiting thread by waking |
* it up. |
/** |
* Signal the condition has become true |
* to the first waiting thread by waking it up. |
* |
* @param cv Condition variable. |
* @param cv Condition variable. |
*/ |
void condvar_signal(condvar_t *cv) |
{ |
60,10 → 61,11 |
waitq_wakeup(&cv->wq, WAKEUP_FIRST); |
} |
/** Signal the condition has become true to all waiting threads by waking |
* them up. |
/** |
* Signal the condition has become true |
* to all waiting threads by waking them up. |
* |
* @param cv Condition variable. |
* @param cv Condition variable. |
*/ |
void condvar_broadcast(condvar_t *cv) |
{ |
72,17 → 74,17 |
/** Wait for the condition becoming true. |
* |
* @param cv Condition variable. |
* @param mtx Mutex. |
* @param usec Timeout value in microseconds. |
* @param flags Select mode of operation. |
* @param cv Condition variable. |
* @param mtx Mutex. |
* @param usec Timeout value in microseconds. |
* @param flags Select mode of operation. |
* |
* For exact description of meaning of possible combinations of usec and flags, |
* see comment for waitq_sleep_timeout(). Note that when |
* SYNCH_FLAGS_NON_BLOCKING is specified here, ESYNCH_WOULD_BLOCK is always |
* returned. |
* For exact description of meaning of possible combinations |
* of usec and flags, see comment for waitq_sleep_timeout(). |
* Note that when SYNCH_FLAGS_NON_BLOCKING is specified here, |
* ESYNCH_WOULD_BLOCK is always returned. |
* |
* @return See comment for waitq_sleep_timeout(). |
* @return See comment for waitq_sleep_timeout(). |
*/ |
int _condvar_wait_timeout(condvar_t *cv, mutex_t *mtx, uint32_t usec, int flags) |
{ |
/branches/dd/kernel/generic/src/synch/mutex.c |
---|
38,54 → 38,42 |
#include <synch/mutex.h> |
#include <synch/semaphore.h> |
#include <synch/synch.h> |
#include <debug.h> |
/** Initialize mutex. |
/** Initialize mutex |
* |
* @param mtx Mutex. |
* @param type Type of the mutex. |
* Initialize mutex. |
* |
* @param mtx Mutex. |
*/ |
void mutex_initialize(mutex_t *mtx, mutex_type_t type) |
void mutex_initialize(mutex_t *mtx) |
{ |
mtx->type = type; |
semaphore_initialize(&mtx->sem, 1); |
} |
/** Acquire mutex. |
/** Acquire mutex |
* |
* Acquire mutex. |
* Timeout mode and non-blocking mode can be requested. |
* |
* @param mtx Mutex. |
* @param usec Timeout in microseconds. |
* @param flags Specify mode of operation. |
* @param mtx Mutex. |
* @param usec Timeout in microseconds. |
* @param flags Specify mode of operation. |
* |
* For exact description of possible combinations of |
* usec and flags, see comment for waitq_sleep_timeout(). |
* |
* @return See comment for waitq_sleep_timeout(). |
* @return See comment for waitq_sleep_timeout(). |
*/ |
int _mutex_lock_timeout(mutex_t *mtx, uint32_t usec, int flags) |
{ |
int rc; |
if (mtx->type == MUTEX_PASSIVE) { |
rc = _semaphore_down_timeout(&mtx->sem, usec, flags); |
} else { |
ASSERT(mtx->type == MUTEX_ACTIVE); |
ASSERT(usec == SYNCH_NO_TIMEOUT); |
ASSERT(!(flags & SYNCH_FLAGS_INTERRUPTIBLE)); |
do { |
rc = semaphore_trydown(&mtx->sem); |
} while (SYNCH_FAILED(rc) && |
!(flags & SYNCH_FLAGS_NON_BLOCKING)); |
} |
return rc; |
return _semaphore_down_timeout(&mtx->sem, usec, flags); |
} |
/** Release mutex. |
/** Release mutex |
* |
* @param mtx Mutex. |
* Release mutex. |
* |
* @param mtx Mutex. |
*/ |
void mutex_unlock(mutex_t *mtx) |
{ |
/branches/dd/kernel/generic/src/time/timeout.c |
---|
113,7 → 113,7 |
spinlock_lock(&t->lock); |
if (t->cpu) |
panic("Unexpected: t->cpu != 0."); |
panic("t->cpu != 0"); |
t->cpu = CPU; |
t->ticks = us2ticks(time); |
/branches/dd/kernel/generic/src/time/clock.c |
---|
79,7 → 79,7 |
faddr = frame_alloc(ONE_FRAME, FRAME_ATOMIC); |
if (!faddr) |
panic("Cannot allocate page for clock."); |
panic("Cannot allocate page for clock"); |
uptime = (uptime_t *) PA2KA(faddr); |
88,7 → 88,9 |
uptime->useconds = 0; |
clock_parea.pbase = (uintptr_t) faddr; |
clock_parea.vbase = (uintptr_t) uptime; |
clock_parea.frames = 1; |
clock_parea.cacheable = true; |
ddi_parea_register(&clock_parea); |
/* |
187,19 → 189,7 |
spinlock_unlock(&THREAD->lock); |
if (!ticks && !PREEMPTION_DISABLED) { |
#ifdef CONFIG_UDEBUG |
istate_t *istate; |
#endif |
scheduler(); |
#ifdef CONFIG_UDEBUG |
/* |
* Give udebug chance to stop the thread |
* before it begins executing userspace code. |
*/ |
istate = THREAD->udebug.uspace_state; |
if (istate && istate_from_uspace(istate)) |
udebug_before_thread_runs(); |
#endif |
} |
} |
/branches/dd/kernel/generic/src/proc/program.c |
---|
File deleted |
/branches/dd/kernel/generic/src/proc/thread.c |
---|
67,13 → 67,9 |
#include <main/uinit.h> |
#include <syscall/copy.h> |
#include <errno.h> |
#include <console/klog.h> |
#ifndef LOADED_PROG_STACK_PAGES_NO |
#define LOADED_PROG_STACK_PAGES_NO 1 |
#endif |
/** Thread states */ |
char *thread_states[] = { |
"Invalid", |
102,7 → 98,7 |
thread_id_t last_tid = 0; |
static slab_cache_t *thread_slab; |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
slab_cache_t *fpu_context_slab; |
#endif |
161,7 → 157,7 |
/* call the architecture-specific part of the constructor */ |
thr_constructor_arch(t); |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
#ifdef CONFIG_FPU_LAZY |
t->saved_fpu_context = NULL; |
#else |
169,11 → 165,11 |
if (!t->saved_fpu_context) |
return -1; |
#endif |
#endif |
#endif |
t->kstack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | kmflags); |
if (!t->kstack) { |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
if (t->saved_fpu_context) |
slab_free(fpu_context_slab, t->saved_fpu_context); |
#endif |
180,10 → 176,6 |
return -1; |
} |
#ifdef CONFIG_UDEBUG |
mutex_initialize(&t->udebug.lock, MUTEX_PASSIVE); |
#endif |
return 0; |
} |
196,7 → 188,7 |
thr_destructor_arch(t); |
frame_free(KA2PA(t->kstack)); |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
if (t->saved_fpu_context) |
slab_free(fpu_context_slab, t->saved_fpu_context); |
#endif |
211,11 → 203,11 |
void thread_init(void) |
{ |
THREAD = NULL; |
atomic_set(&nrdy, 0); |
atomic_set(&nrdy,0); |
thread_slab = slab_cache_create("thread_slab", sizeof(thread_t), 0, |
thr_constructor, thr_destructor, 0); |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
fpu_context_slab = slab_cache_create("fpu_slab", sizeof(fpu_context_t), |
FPU_CONTEXT_ALIGN, NULL, NULL, 0); |
#endif |
279,7 → 271,7 |
* guarantee that the task won't cease to exist during the |
* call. The task's lock may not be held. |
* @param flags Thread flags. |
* @param name Symbolic name (a copy is made). |
* @param name Symbolic name. |
* @param uncounted Thread's accounting doesn't affect accumulated task |
* accounting. |
* |
297,7 → 289,8 |
return NULL; |
/* Not needed, but good for debugging */ |
memsetb(t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, 0); |
memsetb((uintptr_t) t->kstack, THREAD_STACK_SIZE * 1 << STACK_FRAMES, |
0); |
ipl = interrupts_disable(); |
spinlock_lock(&tidlock); |
316,7 → 309,6 |
interrupts_restore(ipl); |
memcpy(t->name, name, THREAD_NAME_BUFLEN); |
t->name[THREAD_NAME_BUFLEN - 1] = '\0'; |
t->thread_code = func; |
t->thread_arg = arg; |
352,11 → 344,6 |
avltree_node_initialize(&t->threads_tree_node); |
t->threads_tree_node.key = (uintptr_t) t; |
#ifdef CONFIG_UDEBUG |
/* Init debugging stuff */ |
udebug_thread_initialize(&t->udebug); |
#endif |
/* might depend on previous initialization */ |
thread_create_arch(t); |
419,17 → 406,12 |
ipl_t ipl; |
/* |
* Attach to the specified task. |
* Attach to the current task. |
*/ |
ipl = interrupts_disable(); |
spinlock_lock(&task->lock); |
atomic_inc(&task->refcount); |
/* Must not count kbox thread into lifecount */ |
if (t->flags & THREAD_FLAG_USPACE) |
atomic_inc(&task->lifecount); |
atomic_inc(&task->lifecount); |
list_append(&t->th_link, &task->th_head); |
spinlock_unlock(&task->lock); |
452,22 → 434,18 |
{ |
ipl_t ipl; |
if (THREAD->flags & THREAD_FLAG_USPACE) { |
#ifdef CONFIG_UDEBUG |
/* Generate udebug THREAD_E event */ |
udebug_thread_e_event(); |
#endif |
if (atomic_predec(&TASK->lifecount) == 0) { |
/* |
* We are the last userspace thread in the task that |
* still has not exited. With the exception of the |
* moment the task was created, new userspace threads |
* can only be created by threads of the same task. |
* We are safe to perform cleanup. |
*/ |
if (atomic_predec(&TASK->lifecount) == 0) { |
/* |
* We are the last thread in the task that still has not exited. |
* With the exception of the moment the task was created, new |
* threads can only be created by threads of the same task. |
* We are safe to perform cleanup. |
*/ |
if (THREAD->flags & THREAD_FLAG_USPACE) { |
ipc_cleanup(); |
futex_cleanup(); |
LOG("Cleanup of task %" PRIu64" completed.", TASK->taskid); |
futex_cleanup(); |
klog_printf("Cleanup of task %llu completed.", |
TASK->taskid); |
} |
} |
603,37 → 581,33 |
static bool thread_walker(avltree_node_t *node, void *arg) |
{ |
thread_t *t = avltree_get_instance(node, thread_t, threads_tree_node); |
thread_t *t; |
t = avltree_get_instance(node, thread_t, threads_tree_node); |
uint64_t cycles; |
char suffix; |
order(t->cycles, &cycles, &suffix); |
#ifdef __32_BITS__ |
printf("%-6" PRIu64" %-10s %10p %-8s %10p %-3" PRIu32 " %10p %10p %9" PRIu64 "%c ", |
t->tid, t->name, t, thread_states[t->state], t->task, |
t->task->context, t->thread_code, t->kstack, cycles, suffix); |
#endif |
#ifdef __64_BITS__ |
printf("%-6" PRIu64" %-10s %18p %-8s %18p %-3" PRIu32 " %18p %18p %9" PRIu64 "%c ", |
t->tid, t->name, t, thread_states[t->state], t->task, |
t->task->context, t->thread_code, t->kstack, cycles, suffix); |
#endif |
if (sizeof(void *) == 4) |
printf("%-6llu %-10s %#10zx %-8s %#10zx %-3ld %#10zx %#10zx %9llu%c ", |
t->tid, t->name, t, thread_states[t->state], t->task, |
t->task->context, t->thread_code, t->kstack, cycles, suffix); |
else |
printf("%-6llu %-10s %#18zx %-8s %#18zx %-3ld %#18zx %#18zx %9llu%c ", |
t->tid, t->name, t, thread_states[t->state], t->task, |
t->task->context, t->thread_code, t->kstack, cycles, suffix); |
if (t->cpu) |
printf("%-4u", t->cpu->id); |
printf("%-4zd", t->cpu->id); |
else |
printf("none"); |
if (t->state == Sleeping) { |
#ifdef __32_BITS__ |
printf(" %10p", t->sleep_queue); |
#endif |
#ifdef __64_BITS__ |
printf(" %18p", t->sleep_queue); |
#endif |
if (sizeof(uintptr_t) == 4) |
printf(" %#10zx", t->sleep_queue); |
else |
printf(" %#18zx", t->sleep_queue); |
} |
printf("\n"); |
649,25 → 623,23 |
/* Messing with thread structures, avoid deadlock */ |
ipl = interrupts_disable(); |
spinlock_lock(&threads_lock); |
if (sizeof(uintptr_t) == 4) { |
printf("tid name address state task " |
"ctx code stack cycles cpu " |
"waitqueue\n"); |
printf("------ ---------- ---------- -------- ---------- " |
"--- ---------- ---------- ---------- ---- " |
"----------\n"); |
} else { |
printf("tid name address state task " |
"ctx code stack cycles cpu " |
"waitqueue\n"); |
printf("------ ---------- ------------------ -------- ------------------ " |
"--- ------------------ ------------------ ---------- ---- " |
"------------------\n"); |
} |
#ifdef __32_BITS__ |
printf("tid name address state task " |
"ctx code stack cycles cpu " |
"waitqueue\n"); |
printf("------ ---------- ---------- -------- ---------- " |
"--- ---------- ---------- ---------- ---- " |
"----------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("tid name address state task " |
"ctx code stack cycles cpu " |
"waitqueue\n"); |
printf("------ ---------- ------------------ -------- ------------------ " |
"--- ------------------ ------------------ ---------- ---- " |
"------------------\n"); |
#endif |
avltree_walk(&threads_tree, thread_walker, NULL); |
spinlock_unlock(&threads_lock); |
692,6 → 664,7 |
return node != NULL; |
} |
/** Update accounting of current thread. |
* |
* Note that thread_lock on THREAD must be already held and |
709,7 → 682,7 |
* |
*/ |
unative_t sys_thread_create(uspace_arg_t *uspace_uarg, char *uspace_name, |
size_t name_len, thread_id_t *uspace_thread_id) |
thread_id_t *uspace_thread_id) |
{ |
thread_t *t; |
char namebuf[THREAD_NAME_BUFLEN]; |
716,15 → 689,10 |
uspace_arg_t *kernel_uarg; |
int rc; |
if (name_len > THREAD_NAME_BUFLEN - 1) |
name_len = THREAD_NAME_BUFLEN - 1; |
rc = copy_from_uspace(namebuf, uspace_name, name_len); |
rc = copy_from_uspace(namebuf, uspace_name, THREAD_NAME_BUFLEN); |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = '\0'; |
/* |
* In case of failure, kernel_uarg will be deallocated in this function. |
* In case of success, kernel_uarg will be freed in uinit(). |
763,18 → 731,7 |
return (unative_t) rc; |
} |
} |
#ifdef CONFIG_UDEBUG |
/* |
* Generate udebug THREAD_B event and attach the thread. |
* This must be done atomically (with the debug locks held), |
* otherwise we would either miss some thread or receive |
* THREAD_B events for threads that already existed |
* and could be detected with THREAD_READ before. |
*/ |
udebug_thread_b_event_attach(t, TASK); |
#else |
thread_attach(t, TASK); |
#endif |
thread_ready(t); |
return 0; |
/branches/dd/kernel/generic/src/proc/task.c |
---|
35,8 → 35,10 |
* @brief Task management. |
*/ |
#include <main/uinit.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
#include <mm/slab.h> |
#include <atomic.h> |
43,18 → 45,23 |
#include <synch/spinlock.h> |
#include <synch/waitq.h> |
#include <arch.h> |
#include <arch/barrier.h> |
#include <panic.h> |
#include <adt/avl.h> |
#include <adt/btree.h> |
#include <adt/list.h> |
#include <ipc/ipc.h> |
#include <ipc/ipcrsc.h> |
#include <security/cap.h> |
#include <memstr.h> |
#include <print.h> |
#include <lib/elf.h> |
#include <errno.h> |
#include <func.h> |
#include <string.h> |
#include <syscall/copy.h> |
#ifndef LOADED_PROG_STACK_PAGES_NO |
#define LOADED_PROG_STACK_PAGES_NO 1 |
#endif |
/** Spinlock protecting the tasks_tree AVL tree. */ |
SPINLOCK_INITIALIZE(tasks_lock); |
72,7 → 79,11 |
static task_id_t task_counter = 0; |
/** Initialize kernel tasks support. */ |
/** Initialize tasks |
* |
* Initialize kernel tasks support. |
* |
*/ |
void task_init(void) |
{ |
TASK = NULL; |
80,8 → 91,7 |
} |
/* |
* The idea behind this walker is to remember a single task different from |
* TASK. |
* The idea behind this walker is to remember a single task different from TASK. |
*/ |
static bool task_done_walker(avltree_node_t *node, void *arg) |
{ |
96,7 → 106,9 |
return true; /* continue the walk */ |
} |
/** Kill all tasks except the current task. */ |
/** Kill all tasks except the current task. |
* |
*/ |
void task_done(void) |
{ |
task_t *t; |
116,7 → 128,7 |
interrupts_restore(ipl); |
#ifdef CONFIG_DEBUG |
printf("Killing task %" PRIu64 "\n", id); |
printf("Killing task %llu\n", id); |
#endif |
task_kill(id); |
thread_usleep(10000); |
128,13 → 140,15 |
} while (t != NULL); |
} |
/** Create new task with no threads. |
/** Create new task |
* |
* @param as Task's address space. |
* @param name Symbolic name (a copy is made). |
* Create new task with no threads. |
* |
* @return New task's structure. |
* @param as Task's address space. |
* @param name Symbolic name. |
* |
* @return New task's structure |
* |
*/ |
task_t *task_create(as_t *as, char *name) |
{ |
149,10 → 163,7 |
spinlock_initialize(&ta->lock, "task_ta_lock"); |
list_initialize(&ta->th_head); |
ta->as = as; |
memcpy(ta->name, name, TASK_NAME_BUFLEN); |
ta->name[TASK_NAME_BUFLEN - 1] = '\0'; |
ta->name = name; |
atomic_set(&ta->refcount, 0); |
atomic_set(&ta->lifecount, 0); |
ta->context = CONTEXT; |
159,18 → 170,7 |
ta->capabilities = 0; |
ta->cycles = 0; |
#ifdef CONFIG_UDEBUG |
/* Init debugging stuff */ |
udebug_task_init(&ta->udebug); |
/* Init kbox stuff */ |
ipc_answerbox_init(&ta->kb.box, ta); |
ta->kb.thread = NULL; |
mutex_initialize(&ta->kb.cleanup_lock, MUTEX_PASSIVE); |
ta->kb.finished = false; |
#endif |
ipc_answerbox_init(&ta->answerbox, ta); |
for (i = 0; i < IPC_MAX_PHONES; i++) |
ipc_phone_init(&ta->phones[i]); |
179,7 → 179,7 |
ipc_phone_connect(&ta->phones[0], ipc_phone_0); |
atomic_set(&ta->active_calls, 0); |
mutex_initialize(&ta->futexes_lock, MUTEX_PASSIVE); |
mutex_initialize(&ta->futexes_lock); |
btree_create(&ta->futexes); |
ipl = interrupts_disable(); |
202,7 → 202,7 |
/** Destroy task. |
* |
* @param t Task to be destroyed. |
* @param t Task to be destroyed. |
*/ |
void task_destroy(task_t *t) |
{ |
233,63 → 233,90 |
TASK = NULL; |
} |
/** Syscall for reading task ID from userspace. |
/** Create new task with 1 thread and run it |
* |
* @param uspace_task_id userspace address of 8-byte buffer |
* where to store current task ID. |
* @param program_addr Address of program executable image. |
* @param name Program name. |
* |
* @return Zero on success or an error code from @ref errno.h. |
* @return Task of the running program or NULL on error. |
*/ |
unative_t sys_task_get_id(task_id_t *uspace_task_id) |
task_t *task_run_program(void *program_addr, char *name) |
{ |
as_t *as; |
as_area_t *a; |
unsigned int rc; |
thread_t *t; |
task_t *task; |
uspace_arg_t *kernel_uarg; |
as = as_create(0); |
ASSERT(as); |
rc = elf_load((elf_header_t *) program_addr, as); |
if (rc != EE_OK) { |
as_destroy(as); |
return NULL; |
} |
kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0); |
kernel_uarg->uspace_entry = |
(void *) ((elf_header_t *) program_addr)->e_entry; |
kernel_uarg->uspace_stack = (void *) USTACK_ADDRESS; |
kernel_uarg->uspace_thread_function = NULL; |
kernel_uarg->uspace_thread_arg = NULL; |
kernel_uarg->uspace_uarg = NULL; |
task = task_create(as, name); |
ASSERT(task); |
/* |
* No need to acquire lock on TASK because taskid remains constant for |
* the lifespan of the task. |
* Create the data as_area. |
*/ |
return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
sizeof(TASK->taskid)); |
a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE, |
LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS, |
AS_AREA_ATTR_NONE, &anon_backend, NULL); |
/* |
* Create the main thread. |
*/ |
t = thread_create(uinit, kernel_uarg, task, THREAD_FLAG_USPACE, |
"uinit", false); |
ASSERT(t); |
thread_ready(t); |
return task; |
} |
/** Syscall for setting the task name. |
/** Syscall for reading task ID from userspace. |
* |
* The name simplifies identifying the task in the task list. |
* @param uspace_task_id Userspace address of 8-byte buffer where to store |
* current task ID. |
* |
* @param name The new name for the task. (typically the same |
* as the command used to execute it). |
* |
* @return 0 on success or an error code from @ref errno.h. |
*/ |
unative_t sys_task_set_name(const char *uspace_name, size_t name_len) |
unative_t sys_task_get_id(task_id_t *uspace_task_id) |
{ |
int rc; |
char namebuf[TASK_NAME_BUFLEN]; |
/* Cap length of name and copy it from userspace. */ |
if (name_len > TASK_NAME_BUFLEN - 1) |
name_len = TASK_NAME_BUFLEN - 1; |
rc = copy_from_uspace(namebuf, uspace_name, name_len); |
if (rc != 0) |
return (unative_t) rc; |
namebuf[name_len] = '\0'; |
strncpy(TASK->name, namebuf, TASK_NAME_BUFLEN); |
return EOK; |
/* |
* No need to acquire lock on TASK because taskid |
* remains constant for the lifespan of the task. |
*/ |
return (unative_t) copy_to_uspace(uspace_task_id, &TASK->taskid, |
sizeof(TASK->taskid)); |
} |
/** Find task structure corresponding to task ID. |
* |
* The tasks_lock must be already held by the caller of this function and |
* interrupts must be disabled. |
* The tasks_lock must be already held by the caller of this function |
* and interrupts must be disabled. |
* |
* @param id Task ID. |
* @param id Task ID. |
* |
* @return Task structure address or NULL if there is no such task |
* ID. |
* @return Task structure address or NULL if there is no such task ID. |
*/ |
task_t *task_find_by_id(task_id_t id) { avltree_node_t *node; |
task_t *task_find_by_id(task_id_t id) |
{ |
avltree_node_t *node; |
node = avltree_search(&tasks_tree, (avltree_key_t) id); |
300,13 → 327,11 |
/** Get accounting data of given task. |
* |
* Note that task lock of 't' must be already held and interrupts must be |
* already disabled. |
* Note that task lock of 't' must be already held and |
* interrupts must be already disabled. |
* |
* @param t Pointer to thread. |
* @param t Pointer to thread. |
* |
* @return Number of cycles used by the task and all its threads |
* so far. |
*/ |
uint64_t task_get_accounting(task_t *t) |
{ |
338,9 → 363,9 |
* This function is idempotent. |
* It signals all the task's threads to bail it out. |
* |
* @param id ID of the task to be killed. |
* @param id ID of the task to be killed. |
* |
* @return Zero on success or an error code from errno.h. |
* @return 0 on success or an error code from errno.h |
*/ |
int task_kill(task_id_t id) |
{ |
361,7 → 386,7 |
spinlock_unlock(&tasks_lock); |
/* |
* Interrupt all threads. |
* Interrupt all threads except ktaskclnp. |
*/ |
spinlock_lock(&ta->lock); |
for (cur = ta->th_head.next; cur != &ta->th_head; cur = cur->next) { |
369,7 → 394,7 |
bool sleeping = false; |
thr = list_get_instance(cur, thread_t, th_link); |
spinlock_lock(&thr->lock); |
thr->interrupted = true; |
if (thr->state == Sleeping) |
395,22 → 420,18 |
uint64_t cycles; |
char suffix; |
order(task_get_accounting(t), &cycles, &suffix); |
#ifdef __32_BITS__ |
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %10p %10p %9" PRIu64 |
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, |
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
#endif |
#ifdef __64_BITS__ |
printf("%-6" PRIu64 " %-12s %-3" PRIu32 " %18p %18p %9" PRIu64 |
"%c %7ld %6ld", t->taskid, t->name, t->context, t, t->as, cycles, |
suffix, atomic_get(&t->refcount), atomic_get(&t->active_calls)); |
#endif |
if (sizeof(void *) == 4) |
printf("%-6llu %-10s %-3ld %#10zx %#10zx %9llu%c %7zd %6zd", |
t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
t->refcount, atomic_get(&t->active_calls)); |
else |
printf("%-6llu %-10s %-3ld %#18zx %#18zx %9llu%c %7zd %6zd", |
t->taskid, t->name, t->context, t, t->as, cycles, suffix, |
t->refcount, atomic_get(&t->active_calls)); |
for (j = 0; j < IPC_MAX_PHONES; j++) { |
if (t->phones[j].callee) |
printf(" %d:%p", j, t->phones[j].callee); |
printf(" %zd:%#zx", j, t->phones[j].callee); |
} |
printf("\n"); |
426,21 → 447,19 |
/* Messing with task structures, avoid deadlock */ |
ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
if (sizeof(void *) == 4) { |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
printf("------ ---------- --- ---------- ---------- " |
"---------- ------- ------ ------>\n"); |
} else { |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
printf("------ ---------- --- ------------------ ------------------ " |
"---------- ------- ------ ------>\n"); |
} |
#ifdef __32_BITS__ |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
printf("------ ------------ --- ---------- ---------- " |
"---------- ------- ------ ------>\n"); |
#endif |
#ifdef __64_BITS__ |
printf("taskid name ctx address as " |
"cycles threads calls callee\n"); |
printf("------ ------------ --- ------------------ ------------------ " |
"---------- ------- ------ ------>\n"); |
#endif |
avltree_walk(&tasks_tree, task_print_walker, NULL); |
spinlock_unlock(&tasks_lock); |
/branches/dd/kernel/generic/src/proc/tasklet.c |
---|
51,7 → 51,7 |
tasklet_list = malloc(sizeof(tasklet_descriptor_t *) * config.cpu_count, 0); |
if (!tasklet_list) |
panic("Error initializing tasklets."); |
panic("Error initializing tasklets"); |
for (i = 0; i < config.cpu_count; i++) |
tasklet_list[i] = NULL; |
/branches/dd/kernel/generic/src/proc/scheduler.c |
---|
451,8 → 451,8 |
/* |
* Entering state is unexpected. |
*/ |
panic("tid%" PRIu64 ": unexpected state %s.", |
THREAD->tid, thread_states[THREAD->state]); |
panic("tid%llu: unexpected state %s\n", THREAD->tid, |
thread_states[THREAD->state]); |
break; |
} |
504,9 → 504,9 |
THREAD->state = Running; |
#ifdef SCHEDULER_VERBOSE |
printf("cpu%u: tid %" PRIu64 " (priority=%d, ticks=%" PRIu64 |
", nrdy=%ld)\n", CPU->id, THREAD->tid, THREAD->priority, |
THREAD->ticks, atomic_get(&CPU->nrdy)); |
printf("cpu%d: tid %llu (priority=%d, ticks=%llu, nrdy=%ld)\n", |
CPU->id, THREAD->tid, THREAD->priority, THREAD->ticks, |
atomic_get(&CPU->nrdy)); |
#endif |
/* |
640,9 → 640,9 |
*/ |
spinlock_lock(&t->lock); |
#ifdef KCPULB_VERBOSE |
printf("kcpulb%u: TID %" PRIu64 " -> cpu%u, " |
"nrdy=%ld, avg=%ld\n", CPU->id, t->tid, |
CPU->id, atomic_get(&CPU->nrdy), |
printf("kcpulb%d: TID %llu -> cpu%d, nrdy=%ld, " |
"avg=%nd\n", CPU->id, t->tid, CPU->id, |
atomic_get(&CPU->nrdy), |
atomic_get(&nrdy) / config.cpu_active); |
#endif |
t->flags |= THREAD_FLAG_STOLEN; |
708,7 → 708,7 |
continue; |
spinlock_lock(&cpus[cpu].lock); |
printf("cpu%u: address=%p, nrdy=%ld, needs_relink=%" PRIc "\n", |
printf("cpu%d: address=%p, nrdy=%ld, needs_relink=%ld\n", |
cpus[cpu].id, &cpus[cpu], atomic_get(&cpus[cpu].nrdy), |
cpus[cpu].needs_relink); |
719,11 → 719,11 |
spinlock_unlock(&r->lock); |
continue; |
} |
printf("\trq[%u]: ", i); |
printf("\trq[%d]: ", i); |
for (cur = r->rq_head.next; cur != &r->rq_head; |
cur = cur->next) { |
t = list_get_instance(cur, thread_t, rq_link); |
printf("%" PRIu64 "(%s) ", t->tid, |
printf("%llu(%s) ", t->tid, |
thread_states[t->state]); |
} |
printf("\n"); |
/branches/dd/kernel/generic/src/debug/symtab.c |
---|
37,10 → 37,8 |
#include <symtab.h> |
#include <byteorder.h> |
#include <string.h> |
#include <func.h> |
#include <print.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/** Return entry that seems most likely to correspond to argument. |
* |
141,7 → 139,7 |
while (symtab_search_one(name, &i)) { |
addr = uint64_t_le2host(symbol_table[i].address_le); |
realname = symbol_table[i].symbol_name; |
printf("%p: %s\n", addr, realname); |
printf("%.*p: %s\n", sizeof(uintptr_t) * 2, addr, realname); |
i++; |
} |
} |
/branches/dd/kernel/generic/src/main/main.c |
---|
61,7 → 61,6 |
#include <main/kinit.h> |
#include <main/version.h> |
#include <console/kconsole.h> |
#include <console/console.h> |
#include <cpu.h> |
#include <align.h> |
#include <interrupt.h> |
79,9 → 78,9 |
#include <ipc/ipc.h> |
#include <macros.h> |
#include <adt/btree.h> |
#include <console/klog.h> |
#include <smp/smp.h> |
#include <ddi/ddi.h> |
#include <main/main.h> |
/** Global configuration structure. */ |
config_t config; |
105,15 → 104,18 |
* appropriate sizes and addresses. |
*/ |
/** Virtual address of where the kernel is loaded. */ |
/**< Virtual address of where the kernel is loaded. */ |
uintptr_t hardcoded_load_address = 0; |
/** Size of the kernel code in bytes. */ |
/**< Size of the kernel code in bytes. */ |
size_t hardcoded_ktext_size = 0; |
/** Size of the kernel data in bytes. */ |
/**< Size of the kernel data in bytes. */ |
size_t hardcoded_kdata_size = 0; |
/** Lowest safe stack virtual address. */ |
/**< Lowest safe stack virtual address. */ |
uintptr_t stack_safe = 0; |
void main_bsp(void); |
void main_ap(void); |
/* |
* These two functions prevent stack from underflowing during the |
* kernel boot phase when SP is set to the very top of the reserved |
129,11 → 131,9 |
/** Main kernel routine for bootstrap CPU. |
* |
* The code here still runs on the boot stack, which knows nothing about |
* preemption counts. Because of that, this function cannot directly call |
* functions that disable or enable preemption (e.g. spinlock_lock()). The |
* primary task of this function is to calculate address of a new stack and |
* switch to it. |
* Initializes the kernel by bootstrap CPU. |
* This function passes control directly to |
* main_bsp_separated_stack(). |
* |
* Assuming interrupts_disable(). |
* |
186,97 → 186,90 |
*/ |
void main_bsp_separated_stack(void) |
{ |
/* Keep this the first thing. */ |
task_t *k; |
thread_t *t; |
count_t i; |
the_initialize(THE); |
version_print(); |
LOG("\nconfig.base=%#" PRIp " config.kernel_size=%" PRIs |
"\nconfig.stack_base=%#" PRIp " config.stack_size=%" PRIs, |
config.base, config.kernel_size, config.stack_base, |
config.stack_size); |
#ifdef CONFIG_KCONSOLE |
/* |
* kconsole data structures must be initialized very early |
* because other subsystems will register their respective |
* commands. |
*/ |
LOG_EXEC(kconsole_init()); |
#endif |
kconsole_init(); |
/* |
* Exception handler initialization, before architecture |
* starts adding its own handlers |
*/ |
LOG_EXEC(exc_init()); |
exc_init(); |
/* |
* Memory management subsystems initialization. |
*/ |
LOG_EXEC(arch_pre_mm_init()); |
LOG_EXEC(frame_init()); |
*/ |
arch_pre_mm_init(); |
frame_init(); |
/* Initialize at least 1 memory segment big enough for slab to work. */ |
LOG_EXEC(slab_cache_init()); |
LOG_EXEC(btree_init()); |
LOG_EXEC(as_init()); |
LOG_EXEC(page_init()); |
LOG_EXEC(tlb_init()); |
LOG_EXEC(ddi_init()); |
LOG_EXEC(tasklet_init()); |
LOG_EXEC(arch_post_mm_init()); |
LOG_EXEC(arch_pre_smp_init()); |
LOG_EXEC(smp_init()); |
slab_cache_init(); |
btree_init(); |
as_init(); |
page_init(); |
tlb_init(); |
ddi_init(); |
tasklet_init(); |
arch_post_mm_init(); |
version_print(); |
printf("kernel: %.*p hardcoded_ktext_size=%zd KB, " |
"hardcoded_kdata_size=%zd KB\n", sizeof(uintptr_t) * 2, |
config.base, SIZE2KB(hardcoded_ktext_size), |
SIZE2KB(hardcoded_kdata_size)); |
printf("stack: %.*p size=%zd KB\n", sizeof(uintptr_t) * 2, |
config.stack_base, SIZE2KB(config.stack_size)); |
arch_pre_smp_init(); |
smp_init(); |
/* Slab must be initialized after we know the number of processors. */ |
LOG_EXEC(slab_enable_cpucache()); |
slab_enable_cpucache(); |
printf("Detected %" PRIc " CPU(s), %" PRIu64" MiB free memory\n", |
config.cpu_count, SIZE2MB(zone_total_size())); |
printf("Detected %zu CPU(s), %llu MB free memory\n", |
config.cpu_count, SIZE2MB(zone_total_size())); |
cpu_init(); |
LOG_EXEC(cpu_init()); |
calibrate_delay_loop(); |
clock_counter_init(); |
timeout_init(); |
scheduler_init(); |
task_init(); |
thread_init(); |
futex_init(); |
klog_init(); |
LOG_EXEC(calibrate_delay_loop()); |
LOG_EXEC(clock_counter_init()); |
LOG_EXEC(timeout_init()); |
LOG_EXEC(scheduler_init()); |
LOG_EXEC(task_init()); |
LOG_EXEC(thread_init()); |
LOG_EXEC(futex_init()); |
if (init.cnt > 0) { |
count_t i; |
for (i = 0; i < init.cnt; i++) |
LOG("init[%" PRIc "].addr=%#" PRIp ", init[%" PRIc |
"].size=%#" PRIs "\n", i, init.tasks[i].addr, i, |
printf("init[%zd].addr=%.*p, init[%zd].size=%zd\n", i, |
sizeof(uintptr_t) * 2, init.tasks[i].addr, i, |
init.tasks[i].size); |
} else |
printf("No init binaries found\n"); |
LOG_EXEC(ipc_init()); |
LOG_EXEC(klog_init()); |
LOG_EXEC(console_init()); |
#ifdef CONFIG_KCONSOLE |
LOG_EXEC(kconsole_notify_init()); |
#endif |
ipc_init(); |
/* |
* Create kernel task. |
*/ |
task_t *kernel = task_create(AS_KERNEL, "kernel"); |
if (!kernel) |
panic("Cannot create kernel task."); |
k = task_create(AS_KERNEL, "kernel"); |
if (!k) |
panic("can't create kernel task\n"); |
/* |
* Create the first thread. |
*/ |
thread_t *kinit_thread |
= thread_create(kinit, NULL, kernel, 0, "kinit", true); |
if (!kinit_thread) |
panic("Cannot create kinit thread."); |
LOG_EXEC(thread_ready(kinit_thread)); |
t = thread_create(kinit, NULL, k, 0, "kinit", true); |
if (!t) |
panic("can't create kinit thread\n"); |
thread_ready(t); |
/* |
* This call to scheduler() will return to kinit, |
329,7 → 322,6 |
* collide with another CPU coming up. To prevent this, we |
* switch to this cpu's private stack prior to waking kmp up. |
*/ |
context_save(&CPU->saved_context); |
context_set(&CPU->saved_context, FADDR(main_ap_separated_stack), |
(uintptr_t) CPU->stack, CPU_STACK_SIZE); |
context_restore(&CPU->saved_context); |
/branches/dd/kernel/generic/src/main/version.c |
---|
34,22 → 34,21 |
#include <main/version.h> |
#include <print.h> |
#include <macros.h> |
char *project = "SPARTAN kernel"; |
char *copyright = "Copyright (c) 2001-2009 HelenOS project"; |
char *release = STRING(RELEASE); |
char *name = STRING(NAME); |
char *arch = STRING(KARCH); |
char *copyright = "Copyright (c) 2001-2008 HelenOS project"; |
char *release = RELEASE; |
char *name = NAME; |
char *arch = ARCH; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = " on " STRING(TIMESTAMP); |
char *timestamp = " on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
/branches/dd/kernel/generic/src/main/uinit.c |
---|
46,9 → 46,7 |
#include <userspace.h> |
#include <mm/slab.h> |
#include <arch.h> |
#include <udebug/udebug.h> |
/** Thread used to bring up userspace thread. |
* |
* @param arg Pointer to structure containing userspace entry and stack |
67,10 → 65,6 |
* deployed for the event of forceful task termination. |
*/ |
thread_detach(THREAD); |
#ifdef CONFIG_UDEBUG |
udebug_stoppable_end(); |
#endif |
uarg.uspace_entry = ((uspace_arg_t *) arg)->uspace_entry; |
uarg.uspace_stack = ((uspace_arg_t *) arg)->uspace_stack; |
/branches/dd/kernel/generic/src/main/kinit.c |
---|
32,7 → 32,7 |
/** |
* @file |
* @brief Kernel initialization thread. |
* @brief Kernel initialization thread. |
* |
* This file contains kinit kernel thread which carries out |
* high level system initialization. |
47,7 → 47,6 |
#include <proc/scheduler.h> |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <proc/program.h> |
#include <panic.h> |
#include <func.h> |
#include <cpu.h> |
64,8 → 63,6 |
#include <security/cap.h> |
#include <lib/rd.h> |
#include <ipc/ipc.h> |
#include <debug.h> |
#include <string.h> |
#ifdef CONFIG_SMP |
#include <smp/smp.h> |
74,15 → 71,6 |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#define ALIVE_CHARS 4 |
#ifdef CONFIG_KCONSOLE |
static char alive[ALIVE_CHARS] = "-\\|/"; |
#endif |
#define INIT_PREFIX "init:" |
#define INIT_PREFIX_LEN 5 |
/** Kernel initialization thread. |
* |
* kinit takes care of higher level kernel |
93,19 → 81,16 |
*/ |
void kinit(void *arg) |
{ |
thread_t *t; |
#if defined(CONFIG_SMP) || defined(CONFIG_KCONSOLE) |
thread_t *thread; |
#endif |
/* |
* Detach kinit as nobody will call thread_join_timeout() on it. |
*/ |
thread_detach(THREAD); |
interrupts_disable(); |
#ifdef CONFIG_SMP |
#ifdef CONFIG_SMP |
if (config.cpu_count > 1) { |
waitq_initialize(&ap_completion_wq); |
/* |
114,18 → 99,24 |
* not mess together with kcpulb threads. |
* Just a beautification. |
*/ |
thread = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, "kmp", true); |
if (thread != NULL) { |
spinlock_lock(&thread->lock); |
thread->cpu = &cpus[0]; |
spinlock_unlock(&thread->lock); |
thread_ready(thread); |
if ((t = thread_create(kmp, NULL, TASK, THREAD_FLAG_WIRED, |
"kmp", true))) { |
spinlock_lock(&t->lock); |
t->cpu = &cpus[0]; |
spinlock_unlock(&t->lock); |
thread_ready(t); |
} else |
panic("Unable to create kmp thread."); |
thread_join(thread); |
thread_detach(thread); |
panic("thread_create/kmp\n"); |
thread_join(t); |
thread_detach(t); |
} |
#endif /* CONFIG_SMP */ |
/* |
* Now that all CPUs are up, we can report what we've found. |
*/ |
cpu_list(); |
#ifdef CONFIG_SMP |
if (config.cpu_count > 1) { |
count_t i; |
133,119 → 124,75 |
* For each CPU, create its load balancing thread. |
*/ |
for (i = 0; i < config.cpu_count; i++) { |
thread = thread_create(kcpulb, NULL, TASK, THREAD_FLAG_WIRED, "kcpulb", true); |
if (thread != NULL) { |
spinlock_lock(&thread->lock); |
thread->cpu = &cpus[i]; |
spinlock_unlock(&thread->lock); |
thread_ready(thread); |
if ((t = thread_create(kcpulb, NULL, TASK, |
THREAD_FLAG_WIRED, "kcpulb", true))) { |
spinlock_lock(&t->lock); |
t->cpu = &cpus[i]; |
spinlock_unlock(&t->lock); |
thread_ready(t); |
} else |
printf("Unable to create kcpulb thread for cpu" PRIc "\n", i); |
panic("thread_create/kcpulb\n"); |
} |
} |
#endif /* CONFIG_SMP */ |
/* |
* At this point SMP, if present, is configured. |
*/ |
arch_post_smp_init(); |
#ifdef CONFIG_KCONSOLE |
if (stdin) { |
/* |
* Create kernel console. |
*/ |
thread = thread_create(kconsole_thread, NULL, TASK, 0, "kconsole", false); |
if (thread != NULL) |
thread_ready(thread); |
else |
printf("Unable to create kconsole thread\n"); |
} |
#endif /* CONFIG_KCONSOLE */ |
interrupts_enable(); |
/* |
* Create user tasks, load RAM disk images. |
* Create kernel console. |
*/ |
t = thread_create(kconsole, (void *) "kconsole", TASK, 0, "kconsole", false); |
if (t) |
thread_ready(t); |
else |
panic("thread_create/kconsole\n"); |
interrupts_enable(); |
count_t i; |
program_t programs[CONFIG_INIT_TASKS]; |
for (i = 0; i < init.cnt; i++) { |
/* |
* Run user tasks, load RAM disk images. |
*/ |
if (init.tasks[i].addr % FRAME_SIZE) { |
printf("init[%" PRIc "].addr is not frame aligned\n", i); |
printf("init[%d].addr is not frame aligned", i); |
continue; |
} |
task_t *utask = task_run_program((void *) init.tasks[i].addr, |
"uspace"); |
/* |
* Construct task name from the 'init:' prefix and the |
* name stored in the init structure (if any). |
*/ |
char namebuf[TASK_NAME_BUFLEN]; |
char *name; |
name = init.tasks[i].name; |
if (name[0] == '\0') |
name = "<unknown>"; |
ASSERT(TASK_NAME_BUFLEN >= INIT_PREFIX_LEN); |
strncpy(namebuf, INIT_PREFIX, TASK_NAME_BUFLEN); |
strncpy(namebuf + INIT_PREFIX_LEN, name, |
TASK_NAME_BUFLEN - INIT_PREFIX_LEN); |
int rc = program_create_from_image((void *) init.tasks[i].addr, |
namebuf, &programs[i]); |
if ((rc == 0) && (programs[i].task != NULL)) { |
if (utask) { |
/* |
* Set capabilities to init userspace tasks. |
*/ |
cap_set(programs[i].task, CAP_CAP | CAP_MEM_MANAGER | |
cap_set(utask, CAP_CAP | CAP_MEM_MANAGER | |
CAP_IO_MANAGER | CAP_PREEMPT_CONTROL | CAP_IRQ_REG); |
if (!ipc_phone_0) |
ipc_phone_0 = &programs[i].task->answerbox; |
} else if (rc == 0) { |
/* It was the program loader and was registered */ |
if (!ipc_phone_0) |
ipc_phone_0 = &utask->answerbox; |
} else { |
/* RAM disk image */ |
int rd = init_rd((rd_header_t *) init.tasks[i].addr, init.tasks[i].size); |
int rd = init_rd((rd_header *) init.tasks[i].addr, |
init.tasks[i].size); |
if (rd != RE_OK) |
printf("Init binary %" PRIc " not used (error %d)\n", i, rd); |
printf("Init binary %zd not used, error code %d.\n", i, rd); |
} |
} |
/* |
* Run user tasks with small delays |
* to avoid intermixed klog output. |
* |
* TODO: This certainly does not guarantee |
* anything, it just works in most of the |
* cases. Some better way how to achieve |
* nice klog output should be found. |
*/ |
for (i = 0; i < init.cnt; i++) { |
if (programs[i].task != NULL) { |
program_ready(&programs[i]); |
thread_usleep(10000); |
} |
} |
#ifdef CONFIG_KCONSOLE |
if (!stdin) { |
thread_sleep(10); |
printf("kinit: No stdin\nKernel alive: ."); |
unsigned int i = 0; |
while (true) { |
printf("\b%c", alive[i % ALIVE_CHARS]); |
while (1) { |
thread_sleep(1); |
i++; |
printf("kinit... "); |
} |
} |
#endif /* CONFIG_KCONSOLE */ |
} |
/** @} |
/branches/dd/kernel/generic/src/interrupt/interrupt.c |
---|
86,17 → 86,8 |
void exc_dispatch(int n, istate_t *istate) |
{ |
ASSERT(n < IVT_ITEMS); |
#ifdef CONFIG_UDEBUG |
if (THREAD) THREAD->udebug.uspace_state = istate; |
#endif |
exc_table[n].f(n + IVT_FIRST, istate); |
#ifdef CONFIG_UDEBUG |
if (THREAD) THREAD->udebug.uspace_state = NULL; |
#endif |
/* This is a safe place to exit exiting thread */ |
if (THREAD && THREAD->interrupted && istate_from_uspace(istate)) |
thread_exit(); |
109,10 → 100,8 |
panic("Unhandled exception %d.", n); |
} |
#ifdef CONFIG_KCONSOLE |
/** kconsole cmd - print all exceptions */ |
static int cmd_exc_print(cmd_arg_t *argv) |
static int exc_print_cmd(cmd_arg_t *argv) |
{ |
#if (IVT_ITEMS > 0) |
unsigned int i; |
119,32 → 108,27 |
char *symbol; |
spinlock_lock(&exctbl_lock); |
#ifdef __32_BITS__ |
printf("Exc Description Handler Symbol\n"); |
printf("--- -------------------- ---------- --------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("Exc Description Handler Symbol\n"); |
printf("--- -------------------- ------------------ --------\n"); |
#endif |
if (sizeof(void *) == 4) { |
printf("Exc Description Handler Symbol\n"); |
printf("--- -------------------- ---------- --------\n"); |
} else { |
printf("Exc Description Handler Symbol\n"); |
printf("--- -------------------- ------------------ --------\n"); |
} |
for (i = 0; i < IVT_ITEMS; i++) { |
symbol = get_symtab_entry((unative_t) exc_table[i].f); |
if (!symbol) |
symbol = "not found"; |
#ifdef __32_BITS__ |
printf("%-3u %-20s %10p %s\n", i + IVT_FIRST, exc_table[i].name, |
exc_table[i].f, symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-3u %-20s %18p %s\n", i + IVT_FIRST, exc_table[i].name, |
exc_table[i].f, symbol); |
#endif |
if (sizeof(void *) == 4) |
printf("%-3u %-20s %#10zx %s\n", i + IVT_FIRST, exc_table[i].name, |
exc_table[i].f, symbol); |
else |
printf("%-3u %-20s %#18zx %s\n", i + IVT_FIRST, exc_table[i].name, |
exc_table[i].f, symbol); |
if (((i + 1) % 20) == 0) { |
printf(" -- Press any key to continue -- "); |
spinlock_unlock(&exctbl_lock); |
160,31 → 144,26 |
return 1; |
} |
static cmd_info_t exc_info = { |
.name = "exc", |
.description = "Print exception table.", |
.func = cmd_exc_print, |
.func = exc_print_cmd, |
.help = NULL, |
.argc = 0, |
.argv = NULL |
}; |
#endif |
/** Initialize generic exception handling support */ |
void exc_init(void) |
{ |
int i; |
for (i = 0; i < IVT_ITEMS; i++) |
for (i=0;i < IVT_ITEMS; i++) |
exc_register(i, "undef", (iroutine) exc_undef); |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&exc_info); |
if (!cmd_register(&exc_info)) |
printf("Cannot register command %s\n", exc_info.name); |
#endif |
panic("could not register command %s\n", exc_info.name); |
} |
/** @} |
/branches/dd/kernel/generic/src/printf/printf_core.c |
---|
40,7 → 40,7 |
#include <print.h> |
#include <arch/arg.h> |
#include <macros.h> |
#include <string.h> |
#include <func.h> |
#include <arch.h> |
/** show prefixes 0x or 0 */ |
75,6 → 75,7 |
PrintfQualifierInt, |
PrintfQualifierLong, |
PrintfQualifierLongLong, |
PrintfQualifierNative, |
PrintfQualifierPointer |
} qualifier_t; |
431,6 → 432,7 |
* - "" Signed or unsigned int (default value).@n |
* - "l" Signed or unsigned long int.@n |
* - "ll" Signed or unsigned long long int.@n |
* - "z" unative_t (non-standard extension).@n |
* |
* |
* CONVERSION:@n |
484,7 → 486,7 |
while ((c = fmt[i])) { |
/* control character */ |
if (c == '%') { |
if (c == '%' ) { |
/* print common characters if any processed */ |
if (i > j) { |
if ((retval = printf_putnchars(&fmt[j], |
534,7 → 536,7 |
} else if (fmt[i] == '*') { |
/* get width value from argument list */ |
i++; |
width = (int) va_arg(ap, int); |
width = (int)va_arg(ap, int); |
if (width < 0) { |
/* negative width sets '-' flag */ |
width *= -1; |
557,7 → 559,7 |
* list. |
*/ |
i++; |
precision = (int) va_arg(ap, int); |
precision = (int)va_arg(ap, int); |
if (precision < 0) { |
/* ignore negative precision */ |
precision = 0; |
583,6 → 585,9 |
qualifier = PrintfQualifierLongLong; |
} |
break; |
case 'z': /* unative_t */ |
qualifier = PrintfQualifierNative; |
break; |
default: |
/* default type */ |
qualifier = PrintfQualifierInt; |
622,7 → 627,7 |
* Integer values |
*/ |
case 'P': /* pointer */ |
flags |= __PRINTF_FLAG_BIGCHARS; |
flags |= __PRINTF_FLAG_BIGCHARS; |
case 'p': |
flags |= __PRINTF_FLAG_PREFIX; |
base = 16; |
665,28 → 670,34 |
switch (qualifier) { |
case PrintfQualifierByte: |
size = sizeof(unsigned char); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierShort: |
size = sizeof(unsigned short); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierInt: |
size = sizeof(unsigned int); |
number = (uint64_t) va_arg(ap, unsigned int); |
number = (uint64_t)va_arg(ap, unsigned int); |
break; |
case PrintfQualifierLong: |
size = sizeof(unsigned long); |
number = (uint64_t) va_arg(ap, unsigned long); |
number = (uint64_t)va_arg(ap, unsigned long); |
break; |
case PrintfQualifierLongLong: |
size = sizeof(unsigned long long); |
number = (uint64_t) va_arg(ap, unsigned long long); |
number = (uint64_t)va_arg(ap, |
unsigned long long); |
break; |
case PrintfQualifierPointer: |
size = sizeof(void *); |
number = (uint64_t) (unsigned long) va_arg(ap, void *); |
number = (uint64_t)(unsigned long)va_arg(ap, |
void *); |
break; |
case PrintfQualifierNative: |
size = sizeof(unative_t); |
number = (uint64_t)va_arg(ap, unative_t); |
break; |
default: /* Unknown qualifier */ |
counter = -counter; |
goto out; |
697,7 → 708,7 |
flags |= __PRINTF_FLAG_NEGATIVE; |
if (size == sizeof(uint64_t)) { |
number = -((int64_t) number); |
number = -((int64_t)number); |
} else { |
number = ~number; |
number &= |
723,7 → 734,7 |
} |
if (i > j) { |
if ((retval = printf_putnchars(&fmt[j], (unative_t) (i - j), |
if ((retval = printf_putnchars(&fmt[j], (unative_t)(i - j), |
ps)) < 0) { /* error */ |
counter = -counter; |
goto out; |
733,6 → 744,7 |
} |
out: |
return counter; |
} |
/branches/dd/kernel/generic/src/printf/vprintf.c |
---|
37,8 → 37,6 |
#include <putchar.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <typedefs.h> |
SPINLOCK_INITIALIZE(printf_lock); /**< vprintf spinlock */ |
62,13 → 60,13 |
{ |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vprintf_write, NULL}; |
ipl_t ipl = interrupts_disable(); |
int irqpri = interrupts_disable(); |
spinlock_lock(&printf_lock); |
int ret = printf_core(fmt, &ps, ap); |
spinlock_unlock(&printf_lock); |
interrupts_restore(ipl); |
interrupts_restore(irqpri); |
return ret; |
} |
/branches/dd/kernel/generic/src/console/cmd.c |
---|
50,7 → 50,6 |
#include <arch.h> |
#include <config.h> |
#include <func.h> |
#include <string.h> |
#include <macros.h> |
#include <debug.h> |
#include <symtab.h> |
399,17 → 398,17 |
.argc = 0 |
}; |
/* Data and methods for 'ipc' command */ |
static int cmd_ipc(cmd_arg_t *argv); |
static cmd_arg_t ipc_argv = { |
/* Data and methods for 'ipc_task' command */ |
static int cmd_ipc_task(cmd_arg_t *argv); |
static cmd_arg_t ipc_task_argv = { |
.type = ARG_TYPE_INT, |
}; |
static cmd_info_t ipc_info = { |
.name = "ipc", |
.description = "ipc <taskid> Show IPC information of given task.", |
.func = cmd_ipc, |
static cmd_info_t ipc_task_info = { |
.name = "ipc_task", |
.description = "ipc_task <taskid> Show IPC information of given task.", |
.func = cmd_ipc_task, |
.argc = 1, |
.argv = &ipc_argv |
.argv = &ipc_task_argv |
}; |
/* Data and methods for 'zone' command */ |
462,7 → 461,7 |
&uptime_info, |
&halt_info, |
&help_info, |
&ipc_info, |
&ipc_task_info, |
&set4_info, |
&slabs_info, |
&symaddr_info, |
502,7 → 501,7 |
for (i = 0; basic_commands[i]; i++) { |
cmd_initialize(basic_commands[i]); |
if (!cmd_register(basic_commands[i])) |
printf("Cannot register command %s\n", basic_commands[i]->name); |
panic("could not register command %s\n", basic_commands[i]->name); |
} |
} |
515,31 → 514,23 |
*/ |
int cmd_help(cmd_arg_t *argv) |
{ |
link_t *cur; |
spinlock_lock(&cmd_lock); |
link_t *cur; |
size_t len = 0; |
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { |
cmd_info_t *hlp; |
hlp = list_get_instance(cur, cmd_info_t, link); |
spinlock_lock(&hlp->lock); |
if (strlen(hlp->name) > len) |
len = strlen(hlp->name); |
spinlock_unlock(&hlp->lock); |
} |
for (cur = cmd_head.next; cur != &cmd_head; cur = cur->next) { |
cmd_info_t *hlp; |
hlp = list_get_instance(cur, cmd_info_t, link); |
spinlock_lock(&hlp->lock); |
printf("%-*s %s\n", len, hlp->name, hlp->description); |
printf("%s - %s\n", hlp->name, hlp->description); |
spinlock_unlock(&hlp->lock); |
} |
spinlock_unlock(&cmd_lock); |
spinlock_unlock(&cmd_lock); |
return 1; |
} |
572,7 → 563,7 |
/* This doesn't have to be very accurate */ |
unative_t sec = uptime->seconds1; |
printf("Up %" PRIun " days, %" PRIun " hours, %" PRIun " minutes, %" PRIun " seconds\n", |
printf("Up %u days, %u hours, %u minutes, %u seconds\n", |
sec / 86400, (sec % 86400) / 3600, (sec % 3600) / 60, sec % 60); |
return 1; |
625,9 → 616,14 |
{ |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(void); |
fncptr_t fptr; |
unative_t (*f)(void); |
#ifdef ia64 |
struct { |
unative_t f; |
unative_t gp; |
} fptr; |
#endif |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
636,9 → 632,15 |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
fnc = (unative_t (*)(void)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call0); |
printf("Calling %s() (%p)\n", symbol, symaddr); |
printf("Result: %#" PRIxn "\n", fnc()); |
printf("Calling %s() (%.*p)\n", symbol, sizeof(uintptr_t) * 2, symaddr); |
#ifdef ia64 |
fptr.f = symaddr; |
fptr.gp = ((unative_t *)cmd_call2)[1]; |
f = (unative_t (*)(void)) &fptr; |
#else |
f = (unative_t (*)(void)) symaddr; |
#endif |
printf("Result: %#zx\n", f()); |
} |
return 1; |
678,10 → 680,15 |
{ |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, ...); |
unative_t (*f)(unative_t,...); |
unative_t arg1 = argv[1].intval; |
fncptr_t fptr; |
#ifdef ia64 |
struct { |
unative_t f; |
unative_t gp; |
}fptr; |
#endif |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
690,9 → 697,16 |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
fnc = (unative_t (*)(unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call1); |
printf("Calling f(%#" PRIxn "): %p: %s\n", arg1, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1)); |
printf("Calling f(%#zx): %.*p: %s\n", arg1, sizeof(uintptr_t) * 2, symaddr, symbol); |
#ifdef ia64 |
fptr.f = symaddr; |
fptr.gp = ((unative_t *)cmd_call2)[1]; |
f = (unative_t (*)(unative_t,...)) &fptr; |
#else |
f = (unative_t (*)(unative_t,...)) symaddr; |
#endif |
printf("Result: %#zx\n", f(arg1)); |
} |
return 1; |
703,11 → 717,16 |
{ |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, unative_t, ...); |
unative_t (*f)(unative_t,unative_t,...); |
unative_t arg1 = argv[1].intval; |
unative_t arg2 = argv[2].intval; |
fncptr_t fptr; |
#ifdef ia64 |
struct { |
unative_t f; |
unative_t gp; |
}fptr; |
#endif |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
716,10 → 735,16 |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
fnc = (unative_t (*)(unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call2); |
printf("Calling f(%#" PRIxn ", %#" PRIxn "): %p: %s\n", |
arg1, arg2, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2)); |
printf("Calling f(0x%zx,0x%zx): %.*p: %s\n", |
arg1, arg2, sizeof(uintptr_t) * 2, symaddr, symbol); |
#ifdef ia64 |
fptr.f = symaddr; |
fptr.gp = ((unative_t *)cmd_call2)[1]; |
f = (unative_t (*)(unative_t,unative_t,...)) &fptr; |
#else |
f = (unative_t (*)(unative_t,unative_t,...)) symaddr; |
#endif |
printf("Result: %#zx\n", f(arg1, arg2)); |
} |
return 1; |
730,12 → 755,17 |
{ |
uintptr_t symaddr; |
char *symbol; |
unative_t (*fnc)(unative_t, unative_t, unative_t, ...); |
unative_t (*f)(unative_t,unative_t,unative_t,...); |
unative_t arg1 = argv[1].intval; |
unative_t arg2 = argv[2].intval; |
unative_t arg3 = argv[3].intval; |
fncptr_t fptr; |
#ifdef ia64 |
struct { |
unative_t f; |
unative_t gp; |
}fptr; |
#endif |
symaddr = get_symbol_addr((char *) argv->buffer); |
if (!symaddr) |
printf("Symbol %s not found.\n", argv->buffer); |
744,10 → 774,16 |
printf("Duplicate symbol, be more specific.\n"); |
} else { |
symbol = get_symtab_entry(symaddr); |
fnc = (unative_t (*)(unative_t, unative_t, unative_t, ...)) arch_construct_function(&fptr, (void *) symaddr, (void *) cmd_call3); |
printf("Calling f(%#" PRIxn ",%#" PRIxn ", %#" PRIxn "): %p: %s\n", |
arg1, arg2, arg3, symaddr, symbol); |
printf("Result: %#" PRIxn "\n", fnc(arg1, arg2, arg3)); |
printf("Calling f(0x%zx,0x%zx, 0x%zx): %.*p: %s\n", |
arg1, arg2, arg3, sizeof(uintptr_t) * 2, symaddr, symbol); |
#ifdef ia64 |
fptr.f = symaddr; |
fptr.gp = ((unative_t *)cmd_call2)[1]; |
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) &fptr; |
#else |
f = (unative_t (*)(unative_t,unative_t,unative_t,...)) symaddr; |
#endif |
printf("Result: %#zx\n", f(arg1, arg2, arg3)); |
} |
return 1; |
820,7 → 856,7 |
} else { |
if (pointer) |
addr = (uint32_t *)(*(unative_t *)addr); |
printf("Writing %#" PRIx64 " -> %p\n", arg1, addr); |
printf("Writing 0x%x -> %.*p\n", arg1, sizeof(uintptr_t) * 2, addr); |
*addr = arg1; |
} |
901,7 → 937,7 |
* |
* return Always 1 |
*/ |
int cmd_ipc(cmd_arg_t * argv) { |
int cmd_ipc_task(cmd_arg_t * argv) { |
ipc_print_task(argv[0].intval); |
return 1; |
} |
940,11 → 976,8 |
int cmd_continue(cmd_arg_t *argv) |
{ |
printf("The kernel will now relinquish the console.\n"); |
release_console(); |
if ((kconsole_notify) && (kconsole_irq.notif_cfg.notify)) |
ipc_irq_send_msg_0(&kconsole_irq); |
printf("Use userspace controls to redraw the screen.\n"); |
arch_release_console(); |
return 1; |
} |
957,23 → 990,18 |
*/ |
int cmd_tests(cmd_arg_t *argv) |
{ |
size_t len = 0; |
test_t *test; |
for (test = tests; test->name != NULL; test++) { |
if (strlen(test->name) > len) |
len = strlen(test->name); |
} |
for (test = tests; test->name != NULL; test++) |
printf("%-*s %s%s\n", len, test->name, test->desc, (test->safe ? "" : " (unsafe)")); |
printf("%s\t\t%s%s\n", test->name, test->desc, (test->safe ? "" : " (unsafe)")); |
printf("%-*s Run all safe tests\n", len, "*"); |
printf("*\t\tRun all safe tests\n"); |
return 1; |
} |
static bool run_test(const test_t *test) |
{ |
printf("%s (%s)\n", test->name, test->desc); |
printf("%s\t\t%s\n", test->name, test->desc); |
/* Update and read thread accounting |
for benchmarking */ |
997,7 → 1025,7 |
char suffix; |
order(dt, &cycles, &suffix); |
printf("Time: %" PRIu64 "%c cycles\n", cycles, suffix); |
printf("Time: %llu%c cycles\n", cycles, suffix); |
if (ret == NULL) { |
printf("Test passed\n"); |
1025,7 → 1053,7 |
} |
for (i = 0; i < cnt; i++) { |
printf("%s (%u/%u) ... ", test->name, i + 1, cnt); |
printf("%s (%d/%d) ... ", test->name, i + 1, cnt); |
/* Update and read thread accounting |
for benchmarking */ |
1053,7 → 1081,7 |
data[i] = dt; |
order(dt, &cycles, &suffix); |
printf("OK (%" PRIu64 "%c cycles)\n", cycles, suffix); |
printf("OK (%llu%c cycles)\n", cycles, suffix); |
} |
if (ret) { |
1066,7 → 1094,7 |
} |
order(sum / (uint64_t) cnt, &cycles, &suffix); |
printf("Average\t\t%" PRIu64 "%c\n", cycles, suffix); |
printf("Average\t\t%llu%c\n", cycles, suffix); |
} |
free(data); |
/branches/dd/kernel/generic/src/console/console.c |
---|
35,59 → 35,30 |
#include <console/console.h> |
#include <console/chardev.h> |
#include <sysinfo/sysinfo.h> |
#include <synch/waitq.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ddi/ddi.h> |
#include <ipc/irq.h> |
#include <arch.h> |
#include <func.h> |
#include <print.h> |
#include <atomic.h> |
#define KLOG_SIZE PAGE_SIZE |
#define KLOG_LATENCY 8 |
/** Kernel log cyclic buffer */ |
static char klog[KLOG_SIZE] __attribute__ ((aligned (PAGE_SIZE))); |
/** Kernel log initialized */ |
static bool klog_inited = false; |
/** First kernel log characters */ |
static index_t klog_start = 0; |
/** Number of valid kernel log characters */ |
static size_t klog_len = 0; |
/** Number of stored (not printed) kernel log characters */ |
static size_t klog_stored = 0; |
/** Number of stored kernel log characters for uspace */ |
static size_t klog_uspace = 0; |
/** Silence output */ |
bool silent = false; |
/** Kernel log spinlock */ |
SPINLOCK_INITIALIZE(klog_lock); |
/** Physical memory area used for klog buffer */ |
static parea_t klog_parea; |
/* |
* For now, we use 0 as INR. |
* However, it is therefore desirable to have architecture specific |
* definition of KLOG_VIRT_INR in the future. |
#define BUFLEN 2048 |
static char debug_buffer[BUFLEN]; |
static size_t offset = 0; |
/** Initialize stdout to something that does not print, but does not fail |
* |
* Save data in some buffer so that it could be retrieved in the debugger |
*/ |
#define KLOG_VIRT_INR 0 |
static void null_putchar(chardev_t *d, const char ch) |
{ |
if (offset >= BUFLEN) |
offset = 0; |
debug_buffer[offset++] = ch; |
} |
static irq_t klog_irq; |
static chardev_operations_t null_stdout_ops = { |
.suspend = NULL, |
.resume = NULL, |
.write = NULL, |
.read = NULL |
.write = null_putchar |
}; |
chardev_t null_stdout = { |
95,88 → 66,10 |
.op = &null_stdout_ops |
}; |
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
*/ |
static irq_ownership_t klog_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
static void stdin_suspend(chardev_t *d) |
{ |
} |
static void stdin_resume(chardev_t *d) |
{ |
} |
static chardev_operations_t stdin_ops = { |
.suspend = stdin_suspend, |
.resume = stdin_resume, |
}; |
/** Standard input character device */ |
static chardev_t _stdin; |
/** Standard input character device. */ |
chardev_t *stdin = NULL; |
chardev_t *stdout = &null_stdout; |
void console_init(void) |
{ |
chardev_initialize("stdin", &_stdin, &stdin_ops); |
stdin = &_stdin; |
} |
/** Initialize kernel logging facility |
* |
* The shared area contains kernel cyclic buffer. Userspace application may |
* be notified on new data with indication of position and size |
* of the data within the circular buffer. |
*/ |
void klog_init(void) |
{ |
void *faddr = (void *) KA2PA(klog); |
ASSERT((uintptr_t) faddr % FRAME_SIZE == 0); |
ASSERT(KLOG_SIZE % FRAME_SIZE == 0); |
devno_t devno = device_assign_devno(); |
klog_parea.pbase = (uintptr_t) faddr; |
klog_parea.frames = SIZE2FRAMES(KLOG_SIZE); |
ddi_parea_register(&klog_parea); |
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr); |
sysinfo_set_item_val("klog.pages", NULL, SIZE2FRAMES(KLOG_SIZE)); |
sysinfo_set_item_val("klog.devno", NULL, devno); |
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR); |
irq_initialize(&klog_irq); |
klog_irq.devno = devno; |
klog_irq.inr = KLOG_VIRT_INR; |
klog_irq.claim = klog_claim; |
irq_register(&klog_irq); |
spinlock_lock(&klog_lock); |
klog_inited = true; |
spinlock_unlock(&klog_lock); |
} |
void grab_console(void) |
{ |
silent = false; |
arch_grab_console(); |
} |
void release_console(void) |
{ |
silent = true; |
arch_release_console(); |
} |
/** Get character from character device. Do not echo character. |
* |
* @param chardev Character device. |
197,10 → 90,10 |
return chardev->op->read(chardev); |
/* no other way of interacting with user, halt */ |
if (CPU) |
printf("cpu%u: ", CPU->id); |
printf("cpu%d: ", CPU->id); |
else |
printf("cpu: "); |
printf("halted (no kconsole)\n"); |
printf("halted - no kconsole\n"); |
cpu_halt(); |
} |
232,7 → 125,7 |
{ |
index_t index = 0; |
char ch; |
while (index < buflen) { |
ch = _getc(chardev); |
if (ch == '\b') { |
246,7 → 139,7 |
continue; |
} |
putchar(ch); |
if (ch == '\n') { /* end of string => write 0, return */ |
buf[index] = '\0'; |
return (count_t) index; |
266,60 → 159,10 |
return ch; |
} |
void klog_update(void) |
{ |
spinlock_lock(&klog_lock); |
if ((klog_inited) && (klog_irq.notif_cfg.notify) && (klog_uspace > 0)) { |
ipc_irq_send_msg_3(&klog_irq, klog_start, klog_len, klog_uspace); |
klog_uspace = 0; |
} |
spinlock_unlock(&klog_lock); |
} |
void putchar(char c) |
{ |
spinlock_lock(&klog_lock); |
if ((klog_stored > 0) && (stdout->op->write)) { |
/* Print charaters stored in kernel log */ |
index_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
stdout->op->write(stdout, klog[(klog_start + i) % KLOG_SIZE], silent); |
klog_stored = 0; |
} |
/* Store character in the cyclic kernel log */ |
klog[(klog_start + klog_len) % KLOG_SIZE] = c; |
if (klog_len < KLOG_SIZE) |
klog_len++; |
else |
klog_start = (klog_start + 1) % KLOG_SIZE; |
if (stdout->op->write) |
stdout->op->write(stdout, c, silent); |
else { |
/* The character is just in the kernel log */ |
if (klog_stored < klog_len) |
klog_stored++; |
} |
/* The character is stored for uspace */ |
if (klog_uspace < klog_len) |
klog_uspace++; |
/* Check notify uspace to update */ |
bool update; |
if ((klog_uspace > KLOG_LATENCY) || (c == '\n')) |
update = true; |
else |
update = false; |
spinlock_unlock(&klog_lock); |
if (update) |
klog_update(); |
stdout->op->write(stdout, c); |
} |
/** @} |
/branches/dd/kernel/generic/src/console/klog.c |
---|
0,0 → 1,154 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genericklog |
* @{ |
*/ |
/** @file |
*/ |
#include <mm/frame.h> |
#include <sysinfo/sysinfo.h> |
#include <console/klog.h> |
#include <print.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <ddi/ddi.h> |
#include <ipc/irq.h> |
/** Physical memory area used for klog. */ |
static parea_t klog_parea; |
/* |
* For now, we use 0 as INR. |
* However, on some architectures 0 is the clock interrupt (e.g. amd64 and |
* ia32). It is therefore desirable to have architecture specific definition of |
* KLOG_VIRT_INR in the future. |
*/ |
#define KLOG_VIRT_INR 0 |
/* Order of frame to be allocated for klog communication */ |
#define KLOG_ORDER 0 |
static char *klog; |
static int klogsize; |
static int klogpos; |
SPINLOCK_INITIALIZE(klog_lock); |
static irq_t klog_irq; |
static irq_ownership_t klog_claim(void); |
/** Initialize kernel logging facility |
* |
* Allocate pages that are to be shared with uspace for console data. |
* The shared area is a circular buffer. Userspace application may |
* be notified on new data with indication of position and size |
* of the data within the circular buffer. |
*/ |
void klog_init(void) |
{ |
void *faddr; |
faddr = frame_alloc(KLOG_ORDER, FRAME_ATOMIC); |
if (!faddr) |
panic("Cannot allocate page for klog"); |
klog = (char *) PA2KA(faddr); |
devno_t devno = device_assign_devno(); |
klog_parea.pbase = (uintptr_t) faddr; |
klog_parea.vbase = (uintptr_t) klog; |
klog_parea.frames = 1 << KLOG_ORDER; |
klog_parea.cacheable = true; |
ddi_parea_register(&klog_parea); |
sysinfo_set_item_val("klog.faddr", NULL, (unative_t) faddr); |
sysinfo_set_item_val("klog.pages", NULL, 1 << KLOG_ORDER); |
sysinfo_set_item_val("klog.devno", NULL, devno); |
sysinfo_set_item_val("klog.inr", NULL, KLOG_VIRT_INR); |
irq_initialize(&klog_irq); |
klog_irq.devno = devno; |
klog_irq.inr = KLOG_VIRT_INR; |
klog_irq.claim = klog_claim; |
irq_register(&klog_irq); |
klogsize = PAGE_SIZE << KLOG_ORDER; |
klogpos = 0; |
} |
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
*/ |
irq_ownership_t klog_claim(void) |
{ |
return IRQ_DECLINE; |
} |
static void klog_vprintf(const char *fmt, va_list args) |
{ |
int ret; |
va_list atst; |
va_copy(atst, args); |
spinlock_lock(&klog_lock); |
ret = vsnprintf(klog+klogpos, klogsize-klogpos, fmt, atst); |
if (ret >= klogsize-klogpos) { |
klogpos = 0; |
if (ret >= klogsize) |
goto out; |
} |
ipc_irq_send_msg_2(&klog_irq, klogpos, ret); |
klogpos += ret; |
if (klogpos >= klogsize) |
klogpos = 0; |
out: |
spinlock_unlock(&klog_lock); |
va_end(atst); |
} |
/** Printf a message to kernel-uspace log */ |
void klog_printf(const char *fmt, ...) |
{ |
va_list args; |
va_start(args, fmt); |
klog_vprintf(fmt, args); |
va_end(args); |
} |
/** @} |
*/ |
/branches/dd/kernel/generic/src/console/kconsole.c |
---|
49,11 → 49,8 |
#include <macros.h> |
#include <debug.h> |
#include <func.h> |
#include <string.h> |
#include <symtab.h> |
#include <macros.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/device.h> |
/** Simple kernel console. |
* |
86,39 → 83,10 |
index_t *end); |
static char history[KCONSOLE_HISTORY][MAX_CMDLINE] = {}; |
/* |
* For now, we use 0 as INR. |
* However, it is therefore desirable to have architecture specific |
* definition of KCONSOLE_VIRT_INR in the future. |
*/ |
#define KCONSOLE_VIRT_INR 0 |
bool kconsole_notify = false; |
irq_t kconsole_irq; |
/** Allways refuse IRQ ownership. |
* |
* This is not a real IRQ, so we always decline. |
* |
* @return Always returns IRQ_DECLINE. |
* |
*/ |
static irq_ownership_t kconsole_claim(irq_t *irq) |
{ |
return IRQ_DECLINE; |
} |
/** Initialize kconsole data structures |
* |
* This is the most basic initialization, almost no |
* other kernel subsystem is ready yet. |
* |
*/ |
/** Initialize kconsole data structures. */ |
void kconsole_init(void) |
{ |
unsigned int i; |
int i; |
cmd_init(); |
for (i = 0; i < KCONSOLE_HISTORY; i++) |
126,29 → 94,6 |
} |
/** Initialize kconsole notification mechanism |
* |
* Initialize the virtual IRQ notification mechanism. |
* |
*/ |
void kconsole_notify_init(void) |
{ |
devno_t devno = device_assign_devno(); |
sysinfo_set_item_val("kconsole.present", NULL, true); |
sysinfo_set_item_val("kconsole.devno", NULL, devno); |
sysinfo_set_item_val("kconsole.inr", NULL, KCONSOLE_VIRT_INR); |
irq_initialize(&kconsole_irq); |
kconsole_irq.devno = devno; |
kconsole_irq.inr = KCONSOLE_VIRT_INR; |
kconsole_irq.claim = kconsole_claim; |
irq_register(&kconsole_irq); |
kconsole_notify = true; |
} |
/** Register kconsole command. |
* |
* @param cmd Structure describing the command. |
224,7 → 169,7 |
} |
/** Try to find a command beginning with prefix */ |
static const char *cmdtab_search_one(const char *name,link_t **startpos) |
static const char * cmdtab_search_one(const char *name,link_t **startpos) |
{ |
size_t namelen = strlen(name); |
const char *curname; |
258,7 → 203,7 |
*/ |
static int cmdtab_compl(char *name) |
{ |
static char output[MAX_SYMBOL_NAME + 1]; |
static char output[MAX_SYMBOL_NAME+1]; |
link_t *startpos = NULL; |
const char *foundtxt; |
int found = 0; |
268,7 → 213,7 |
while ((foundtxt = cmdtab_search_one(name, &startpos))) { |
startpos = startpos->next; |
if (!found) |
strncpy(output, foundtxt, strlen(foundtxt) + 1); |
strncpy(output, foundtxt, strlen(foundtxt)+1); |
else { |
for (i = 0; output[i] && foundtxt[i] && |
output[i] == foundtxt[i]; i++) |
295,11 → 240,11 |
} |
static char *clever_readline(const char *prompt, chardev_t *input) |
static char * clever_readline(const char *prompt, chardev_t *input) |
{ |
static int histposition = 0; |
static char tmp[MAX_CMDLINE + 1]; |
static char tmp[MAX_CMDLINE+1]; |
int curlen = 0, position = 0; |
char *current = history[histposition]; |
int i; |
312,8 → 257,7 |
if (c == '\n') { |
putchar(c); |
break; |
} |
if (c == '\b') { /* Backspace */ |
} if (c == '\b') { /* Backspace */ |
if (position == 0) |
continue; |
for (i = position; i < curlen; i++) |
456,15 → 400,11 |
return current; |
} |
/** Kernel console prompt. |
/** Kernel console managing thread. |
* |
* @param prompt Kernel console prompt (e.g kconsole/panic). |
* @param msg Message to display in the beginning. |
* @param kcon Wait for keypress to show the prompt |
* and never exit. |
* |
*/ |
void kconsole(char *prompt, char *msg, bool kcon) |
void kconsole(void *prompt) |
{ |
cmd_info_t *cmd_info; |
count_t len; |
471,42 → 411,25 |
char *cmdline; |
if (!stdin) { |
LOG("No stdin for kernel console"); |
printf("%s: no stdin\n", __func__); |
return; |
} |
if (msg) |
printf("%s", msg); |
if (kcon) |
_getc(stdin); |
while (true) { |
cmdline = clever_readline((char *) prompt, stdin); |
len = strlen(cmdline); |
if (!len) |
continue; |
cmd_info = parse_cmdline(cmdline, len); |
if (!cmd_info) |
continue; |
if ((!kcon) |
&& (strncmp(cmd_info->name, "exit", min(strlen(cmd_info->name), 5)) == 0)) |
if (strncmp(cmd_info->name, "exit", |
min(strlen(cmd_info->name), 5)) == 0) |
break; |
(void) cmd_info->func(cmd_info->argv); |
} |
} |
/** Kernel console managing thread. |
* |
*/ |
void kconsole_thread(void *data) |
{ |
kconsole("kconsole", "Kernel console ready (press any key to activate)\n", true); |
} |
static int parse_int_arg(char *text, size_t len, unative_t *result) |
{ |
static char symname[MAX_SYMBOL_NAME]; |
620,8 → 543,7 |
buf = (char *) cmd->argv[i].buffer; |
strncpy(buf, (const char *) &cmdline[start], |
min((end - start) + 2, cmd->argv[i].len)); |
buf[min((end - start) + 1, cmd->argv[i].len - 1)] = |
'\0'; |
buf[min((end - start) + 1, cmd->argv[i].len - 1)] = '\0'; |
break; |
case ARG_TYPE_INT: |
if (parse_int_arg(cmdline + start, end - start + 1, |
638,8 → 560,8 |
'\0'; |
cmd->argv[i].intval = (unative_t) buf; |
cmd->argv[i].vartype = ARG_TYPE_STRING; |
} else if (!parse_int_arg(cmdline + start, |
end - start + 1, &cmd->argv[i].intval)) { |
} else if (!parse_int_arg(cmdline + start, end - start + 1, |
&cmd->argv[i].intval)) { |
cmd->argv[i].vartype = ARG_TYPE_INT; |
} else { |
printf("Unrecognized variable argument.\n"); |
/branches/dd/kernel/generic/src/console/chardev.c |
---|
42,7 → 42,7 |
* @param chardev Character device. |
* @param op Implementation of character device operations. |
*/ |
void chardev_initialize(char *name, chardev_t *chardev, |
void chardev_initialize(char *name,chardev_t *chardev, |
chardev_operations_t *op) |
{ |
chardev->name = name; |
/branches/dd/kernel/generic/src/syscall/syscall.c |
---|
38,7 → 38,6 |
#include <syscall/syscall.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <proc/program.h> |
#include <mm/as.h> |
#include <print.h> |
#include <putchar.h> |
47,43 → 46,40 |
#include <debug.h> |
#include <ipc/sysipc.h> |
#include <synch/futex.h> |
#include <synch/smc.h> |
#include <ddi/ddi.h> |
#include <security/cap.h> |
#include <syscall/copy.h> |
#include <sysinfo/sysinfo.h> |
#include <console/console.h> |
#include <udebug/udebug.h> |
#include <console/klog.h> |
/** Print using kernel facility |
* |
* Print to kernel log. |
* |
* Some simulators can print only through kernel. Userspace can use |
* this syscall to facilitate it. |
*/ |
static unative_t sys_klog(int fd, const void * buf, size_t count) |
static unative_t sys_io(int fd, const void * buf, size_t count) |
{ |
size_t i; |
char *data; |
int rc; |
if (count > PAGE_SIZE) |
return ELIMIT; |
data = (char *) malloc(count, 0); |
if (!data) |
return ENOMEM; |
if (count > 0) { |
data = (char *) malloc(count + 1, 0); |
if (!data) |
return ENOMEM; |
rc = copy_from_uspace(data, buf, count); |
if (rc) { |
free(data); |
return rc; |
} |
data[count] = 0; |
printf("%s", data); |
rc = copy_from_uspace(data, buf, count); |
if (rc) { |
free(data); |
} else |
klog_update(); |
return rc; |
} |
for (i = 0; i < count; i++) |
putchar(data[i]); |
free(data); |
return count; |
} |
91,21 → 87,10 |
/** Tell kernel to get keyboard/console access again */ |
static unative_t sys_debug_enable_console(void) |
{ |
#ifdef CONFIG_KCONSOLE |
grab_console(); |
return true; |
#else |
return false; |
#endif |
arch_grab_console(); |
return 0; |
} |
/** Tell kernel to relinquish keyboard/console access */ |
static unative_t sys_debug_disable_console(void) |
{ |
release_console(); |
return true; |
} |
/** Dispatch system call */ |
unative_t syscall_handler(unative_t a1, unative_t a2, unative_t a3, |
unative_t a4, unative_t a5, unative_t a6, unative_t id) |
112,13 → 97,11 |
{ |
unative_t rc; |
#ifdef CONFIG_UDEBUG |
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, 0, false); |
#endif |
if (id < SYSCALL_END) { |
if (id < SYSCALL_END) |
rc = syscall_table[id](a1, a2, a3, a4, a5, a6); |
} else { |
printf("Task %" PRIu64": Unknown syscall %#" PRIxn, TASK->taskid, id); |
else { |
klog_printf("TASK %llu: Unknown syscall id %llx", TASK->taskid, |
id); |
task_kill(TASK->taskid); |
thread_exit(); |
} |
125,22 → 108,12 |
if (THREAD->interrupted) |
thread_exit(); |
#ifdef CONFIG_UDEBUG |
udebug_syscall_event(a1, a2, a3, a4, a5, a6, id, rc, true); |
/* |
* Stopping point needed for tasks that only invoke non-blocking |
* system calls. |
*/ |
udebug_stoppable_begin(); |
udebug_stoppable_end(); |
#endif |
return rc; |
} |
syshandler_t syscall_table[SYSCALL_END] = { |
(syshandler_t) sys_klog, |
(syshandler_t) sys_io, |
(syshandler_t) sys_tls_set, |
/* Thread and task related syscalls. */ |
147,20 → 120,15 |
(syshandler_t) sys_thread_create, |
(syshandler_t) sys_thread_exit, |
(syshandler_t) sys_thread_get_id, |
(syshandler_t) sys_task_get_id, |
(syshandler_t) sys_task_set_name, |
(syshandler_t) sys_program_spawn_loader, |
/* Synchronization related syscalls. */ |
(syshandler_t) sys_futex_sleep_timeout, |
(syshandler_t) sys_futex_wakeup, |
(syshandler_t) sys_smc_coherence, |
/* Address space related syscalls. */ |
(syshandler_t) sys_as_area_create, |
(syshandler_t) sys_as_area_resize, |
(syshandler_t) sys_as_area_change_flags, |
(syshandler_t) sys_as_area_destroy, |
/* IPC related syscalls. */ |
171,7 → 139,6 |
(syshandler_t) sys_ipc_answer_fast, |
(syshandler_t) sys_ipc_answer_slow, |
(syshandler_t) sys_ipc_forward_fast, |
(syshandler_t) sys_ipc_forward_slow, |
(syshandler_t) sys_ipc_wait_for_call, |
(syshandler_t) sys_ipc_hangup, |
(syshandler_t) sys_ipc_register_irq, |
191,10 → 158,7 |
(syshandler_t) sys_sysinfo_value, |
/* Debug calls */ |
(syshandler_t) sys_debug_enable_console, |
(syshandler_t) sys_debug_disable_console, |
(syshandler_t) sys_ipc_connect_kbox |
(syshandler_t) sys_debug_enable_console |
}; |
/** @} |
/branches/dd/kernel/generic/src/adt/avl.c |
---|
43,7 → 43,7 |
* |
* Every node has a pointer to its parent which allows insertion of multiple |
* identical keys into the tree. |
* |
* |
* Be careful when using this tree because of the base atribute which is added |
* to every inserted node key. There is no rule in which order nodes with the |
* same key are visited. |
/branches/dd/kernel/generic/src/adt/btree.c |
---|
124,7 → 124,7 |
lnode = leaf_node; |
if (!lnode) { |
if (btree_search(t, key, &lnode)) { |
panic("B-tree %p already contains key %" PRIu64 ".", t, key); |
panic("B-tree %p already contains key %d\n", t, key); |
} |
} |
224,7 → 224,7 |
lnode = leaf_node; |
if (!lnode) { |
if (!btree_search(t, key, &lnode)) { |
panic("B-tree %p does not contain key %" PRIu64 ".", t, key); |
panic("B-tree %p does not contain key %d\n", t, key); |
} |
} |
524,7 → 524,7 |
return; |
} |
} |
panic("Node %p does not contain key %" PRIu64 ".", node, key); |
panic("node %p does not contain key %d\n", node, key); |
} |
/** Remove key and its right subtree pointer from B-tree node. |
551,7 → 551,7 |
return; |
} |
} |
panic("Node %p does not contain key %" PRIu64 ".", node, key); |
panic("node %p does not contain key %d\n", node, key); |
} |
/** Split full B-tree node and insert new key-value-right-subtree triplet. |
693,7 → 693,7 |
if (subtree == node->subtree[i]) |
return i - (int) (right != false); |
} |
panic("Node %p does not contain subtree %p.", node, subtree); |
panic("node %p does not contain subtree %p\n", node, subtree); |
} |
/** Rotate one key-value-rsubtree triplet from the left sibling to the right sibling. |
970,7 → 970,7 |
printf("("); |
for (i = 0; i < node->keys; i++) { |
printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : ""); |
printf("%llu%s", node->key[i], i < node->keys - 1 ? "," : ""); |
if (node->depth && node->subtree[i]) { |
list_append(&node->subtree[i]->bfs_link, &head); |
} |
992,7 → 992,7 |
printf("("); |
for (i = 0; i < node->keys; i++) |
printf("%" PRIu64 "%s", node->key[i], i < node->keys - 1 ? "," : ""); |
printf("%llu%s", node->key[i], i < node->keys - 1 ? "," : ""); |
printf(")"); |
} |
printf("\n"); |
/branches/dd/kernel/generic/src/adt/hash_table.c |
---|
61,9 → 61,9 |
h->entry = (link_t *) malloc(m * sizeof(link_t), 0); |
if (!h->entry) { |
panic("Cannot allocate memory for hash table."); |
panic("cannot allocate memory for hash table\n"); |
} |
memsetb(h->entry, m * sizeof(link_t), 0); |
memsetb((uintptr_t) h->entry, m * sizeof(link_t), 0); |
for (i = 0; i < m; i++) |
list_initialize(&h->entry[i]); |
/branches/dd/kernel/generic/src/ddi/irq.c |
---|
39,8 → 39,7 |
* |
* This code is designed to support: |
* - multiple devices sharing single IRQ |
* - multiple IRQs per single device |
* - multiple instances of the same device |
* - multiple IRQs per signle device |
* |
* |
* Note about architectures. |
69,11 → 68,8 |
#include <ddi/irq.h> |
#include <adt/hash_table.h> |
#include <mm/slab.h> |
#include <arch/types.h> |
#include <synch/spinlock.h> |
#include <console/console.h> |
#include <memstr.h> |
#include <arch.h> |
#define KEY_INR 0 |
80,22 → 76,13 |
#define KEY_DEVNO 1 |
/** |
* Spinlock protecting the kernel IRQ hash table. |
* Spinlock protecting the hash table. |
* This lock must be taken only when interrupts are disabled. |
*/ |
SPINLOCK_INITIALIZE(irq_kernel_hash_table_lock); |
/** The kernel IRQ hash table. */ |
static hash_table_t irq_kernel_hash_table; |
SPINLOCK_INITIALIZE(irq_hash_table_lock); |
static hash_table_t irq_hash_table; |
/** |
* Spinlock protecting the uspace IRQ hash table. |
* This lock must be taken only when interrupts are disabled. |
*/ |
SPINLOCK_INITIALIZE(irq_uspace_hash_table_lock); |
/** The uspace IRQ hash table. */ |
hash_table_t irq_uspace_hash_table; |
/** |
* Hash table operations for cases when we know that |
* there will be collisions between different keys. |
*/ |
123,9 → 110,6 |
.remove_callback = NULL /* not used */ |
}; |
/** Number of buckets in either of the hash tables. */ |
static count_t buckets; |
/** Initialize IRQ subsystem. |
* |
* @param inrs Numbers of unique IRQ numbers or INRs. |
133,7 → 117,6 |
*/ |
void irq_init(count_t inrs, count_t chains) |
{ |
buckets = chains; |
/* |
* Be smart about the choice of the hash table operations. |
* In cases in which inrs equals the requested number of |
140,17 → 123,10 |
* chains (i.e. where there is no collision between |
* different keys), we can use optimized set of operations. |
*/ |
if (inrs == chains) { |
hash_table_create(&irq_uspace_hash_table, chains, 2, |
&irq_lin_ops); |
hash_table_create(&irq_kernel_hash_table, chains, 2, |
&irq_lin_ops); |
} else { |
hash_table_create(&irq_uspace_hash_table, chains, 2, |
&irq_ht_ops); |
hash_table_create(&irq_kernel_hash_table, chains, 2, |
&irq_ht_ops); |
} |
if (inrs == chains) |
hash_table_create(&irq_hash_table, chains, 2, &irq_lin_ops); |
else |
hash_table_create(&irq_hash_table, chains, 2, &irq_ht_ops); |
} |
/** Initialize one IRQ structure. |
160,12 → 136,21 |
*/ |
void irq_initialize(irq_t *irq) |
{ |
memsetb(irq, sizeof(irq_t), 0); |
link_initialize(&irq->link); |
spinlock_initialize(&irq->lock, "irq.lock"); |
link_initialize(&irq->notif_cfg.link); |
irq->preack = false; |
irq->inr = -1; |
irq->devno = -1; |
irq->trigger = (irq_trigger_t) 0; |
irq->claim = NULL; |
irq->handler = NULL; |
irq->arg = NULL; |
irq->notif_cfg.notify = false; |
irq->notif_cfg.answerbox = NULL; |
irq->notif_cfg.code = NULL; |
irq->notif_cfg.method = 0; |
irq->notif_cfg.counter = 0; |
link_initialize(&irq->notif_cfg.link); |
} |
/** Register IRQ for device. |
172,10 → 157,9 |
* |
* The irq structure must be filled with information |
* about the interrupt source and with the claim() |
* function pointer and handler() function pointer. |
* function pointer and irq_handler() function pointer. |
* |
* @param irq IRQ structure belonging to a device. |
* @return True on success, false on failure. |
* @param irq IRQ structure belonging to a device. |
*/ |
void irq_register(irq_t *irq) |
{ |
186,101 → 170,88 |
}; |
ipl = interrupts_disable(); |
spinlock_lock(&irq_kernel_hash_table_lock); |
spinlock_lock(&irq->lock); |
hash_table_insert(&irq_kernel_hash_table, key, &irq->link); |
spinlock_unlock(&irq->lock); |
spinlock_unlock(&irq_kernel_hash_table_lock); |
spinlock_lock(&irq_hash_table_lock); |
hash_table_insert(&irq_hash_table, key, &irq->link); |
spinlock_unlock(&irq_hash_table_lock); |
interrupts_restore(ipl); |
} |
/** Search and lock the uspace IRQ hash table. |
/** Dispatch the IRQ. |
* |
* We assume this function is only called from interrupt |
* context (i.e. that interrupts are disabled prior to |
* this call). |
* |
* This function attempts to lookup a fitting IRQ |
* structure. In case of success, return with interrupts |
* disabled and holding the respective structure. |
* |
* @param inr Interrupt number (aka inr or irq). |
* |
* @return IRQ structure of the respective device or NULL. |
*/ |
static irq_t *irq_dispatch_and_lock_uspace(inr_t inr) |
irq_t *irq_dispatch_and_lock(inr_t inr) |
{ |
link_t *lnk; |
unative_t key[] = { |
(unative_t) inr, |
(unative_t) -1 /* search will use claim() instead of devno */ |
(unative_t) -1 /* search will use claim() instead of devno */ |
}; |
spinlock_lock(&irq_uspace_hash_table_lock); |
lnk = hash_table_find(&irq_uspace_hash_table, key); |
spinlock_lock(&irq_hash_table_lock); |
lnk = hash_table_find(&irq_hash_table, key); |
if (lnk) { |
irq_t *irq; |
irq = hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq_uspace_hash_table_lock); |
spinlock_unlock(&irq_hash_table_lock); |
return irq; |
} |
spinlock_unlock(&irq_uspace_hash_table_lock); |
return NULL; |
spinlock_unlock(&irq_hash_table_lock); |
return NULL; |
} |
/** Search and lock the kernel IRQ hash table. |
/** Find the IRQ structure corresponding to inr and devno. |
* |
* This functions attempts to lookup the IRQ structure |
* corresponding to its arguments. On success, this |
* function returns with interrups disabled, holding |
* the lock of the respective IRQ structure. |
* |
* This function assumes interrupts are already disabled. |
* |
* @param inr INR being looked up. |
* @param devno Devno being looked up. |
* |
* @return Locked IRQ structure on success or NULL on failure. |
*/ |
static irq_t *irq_dispatch_and_lock_kernel(inr_t inr) |
irq_t *irq_find_and_lock(inr_t inr, devno_t devno) |
{ |
link_t *lnk; |
unative_t key[] = { |
unative_t keys[] = { |
(unative_t) inr, |
(unative_t) -1 /* search will use claim() instead of devno */ |
(unative_t) devno |
}; |
spinlock_lock(&irq_kernel_hash_table_lock); |
lnk = hash_table_find(&irq_kernel_hash_table, key); |
spinlock_lock(&irq_hash_table_lock); |
lnk = hash_table_find(&irq_hash_table, keys); |
if (lnk) { |
irq_t *irq; |
irq = hash_table_get_instance(lnk, irq_t, link); |
spinlock_unlock(&irq_kernel_hash_table_lock); |
spinlock_unlock(&irq_hash_table_lock); |
return irq; |
} |
spinlock_unlock(&irq_kernel_hash_table_lock); |
return NULL; |
} |
spinlock_unlock(&irq_hash_table_lock); |
/** Dispatch the IRQ. |
* |
* We assume this function is only called from interrupt |
* context (i.e. that interrupts are disabled prior to |
* this call). |
* |
* This function attempts to lookup a fitting IRQ |
* structure. In case of success, return with interrupts |
* disabled and holding the respective structure. |
* |
* @param inr Interrupt number (aka inr or irq). |
* |
* @return IRQ structure of the respective device or NULL. |
*/ |
irq_t *irq_dispatch_and_lock(inr_t inr) |
{ |
irq_t *irq; |
/* |
* If the kernel console is silenced, |
* then try first the uspace handlers, |
* eventually fall back to kernel handlers. |
* |
* If the kernel console is active, |
* then do it the other way around. |
*/ |
if (silent) { |
irq = irq_dispatch_and_lock_uspace(inr); |
if (irq) |
return irq; |
return irq_dispatch_and_lock_kernel(inr); |
} |
irq = irq_dispatch_and_lock_kernel(inr); |
if (irq) |
return irq; |
return irq_dispatch_and_lock_uspace(inr); |
return NULL; |
} |
/** Compute hash index for the key. |
299,7 → 270,7 |
index_t irq_ht_hash(unative_t key[]) |
{ |
inr_t inr = (inr_t) key[KEY_INR]; |
return inr % buckets; |
return inr % irq_hash_table.entries; |
} |
/** Compare hash table element with a key. |
333,8 → 304,7 |
spinlock_lock(&irq->lock); |
if (devno == -1) { |
/* Invoked by irq_dispatch_and_lock(). */ |
rv = ((irq->inr == inr) && |
(irq->claim(irq) == IRQ_ACCEPT)); |
rv = ((irq->inr == inr) && (irq->claim() == IRQ_ACCEPT)); |
} else { |
/* Invoked by irq_find_and_lock(). */ |
rv = ((irq->inr == inr) && (irq->devno == devno)); |
393,7 → 363,7 |
spinlock_lock(&irq->lock); |
if (devno == -1) { |
/* Invoked by irq_dispatch_and_lock() */ |
rv = (irq->claim(irq) == IRQ_ACCEPT); |
rv = (irq->claim() == IRQ_ACCEPT); |
} else { |
/* Invoked by irq_find_and_lock() */ |
rv = (irq->devno == devno); |
/branches/dd/kernel/generic/src/ddi/ddi.c |
---|
29,10 → 29,10 |
/** @addtogroup genericddi |
* @{ |
*/ |
/** |
* @file |
* @brief Device Driver Interface functions. |
* @brief Device Driver Interface functions. |
* |
* This file contains functions that comprise the Device Driver Interface. |
* These are the functions for mapping physical memory and enabling I/O |
68,100 → 68,82 |
* |
* @param parea Pointer to physical area structure. |
* |
* @todo This function doesn't check for overlaps. It depends on the kernel to |
* create disjunct physical memory areas. |
*/ |
void ddi_parea_register(parea_t *parea) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&parea_lock); |
/* |
* We don't check for overlaps here as the kernel is pretty sane. |
* TODO: we should really check for overlaps here. |
* However, we should be safe because the kernel is pretty sane and |
* memory of different devices doesn't overlap. |
*/ |
btree_insert(&parea_btree, (btree_key_t) parea->pbase, parea, NULL); |
spinlock_unlock(&parea_lock); |
interrupts_restore(ipl); |
interrupts_restore(ipl); |
} |
/** Map piece of physical memory into virtual address space of current task. |
* |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pages Number of pages to map. |
* @param flags Address space area flags for the mapping. |
* |
* @return 0 on success, EPERM if the caller lacks capabilities to use this |
* syscall, EBADMEM if pf or vf is not page aligned, ENOENT if there |
* is no task matching the specified ID or the physical address space |
* is not enabled for mapping and ENOMEM if there was a problem in |
* creating address space area. |
* |
* syscall, ENOENT if there is no task matching the specified ID or the |
* physical address space is not enabled for mapping and ENOMEM if there |
* was a problem in creating address space area. |
*/ |
static int ddi_physmem_map(uintptr_t pf, uintptr_t vp, count_t pages, int flags) |
{ |
ASSERT(TASK); |
ASSERT((pf % FRAME_SIZE) == 0); |
ASSERT((vp % PAGE_SIZE) == 0); |
ipl_t ipl; |
cap_t caps; |
mem_backend_data_t backend_data; |
backend_data.base = pf; |
backend_data.frames = pages; |
/* |
* Make sure the caller is authorised to make this syscall. |
*/ |
cap_t caps = cap_get(TASK); |
caps = cap_get(TASK); |
if (!(caps & CAP_MEM_MANAGER)) |
return EPERM; |
mem_backend_data_t backend_data; |
backend_data.base = pf; |
backend_data.frames = pages; |
ipl_t ipl = interrupts_disable(); |
/* Find the zone of the physical memory */ |
spinlock_lock(&zones.lock); |
count_t znum = find_zone(ADDR2PFN(pf), pages, 0); |
if (znum == (count_t) -1) { |
/* Frames not found in any zones |
* -> assume it is hardware device and allow mapping |
ipl = interrupts_disable(); |
/* |
* Check if the physical memory area is enabled for mapping. |
* If the architecture supports virtually indexed caches, intercept |
* attempts to create an illegal address alias. |
*/ |
spinlock_lock(&parea_lock); |
parea_t *parea; |
btree_node_t *nodep; |
parea = (parea_t *) btree_search(&parea_btree, (btree_key_t) pf, &nodep); |
if (!parea || parea->frames < pages || ((flags & AS_AREA_CACHEABLE) && |
!parea->cacheable) || (!(flags & AS_AREA_CACHEABLE) && |
parea->cacheable)) { |
/* |
* This physical memory area cannot be mapped. |
*/ |
spinlock_unlock(&zones.lock); |
goto map; |
} |
if (zones.info[znum].flags & ZONE_FIRMWARE) { |
/* Frames are part of firmware */ |
spinlock_unlock(&zones.lock); |
goto map; |
} |
if (zone_flags_available(zones.info[znum].flags)) { |
/* Frames are part of physical memory, check if the memory |
* region is enabled for mapping. |
*/ |
spinlock_unlock(&zones.lock); |
spinlock_lock(&parea_lock); |
btree_node_t *nodep; |
parea_t *parea = (parea_t *) btree_search(&parea_btree, |
(btree_key_t) pf, &nodep); |
if ((!parea) || (parea->frames < pages)) |
goto err; |
spinlock_unlock(&parea_lock); |
goto map; |
interrupts_restore(ipl); |
return ENOENT; |
} |
err: |
spinlock_unlock(&zones.lock); |
interrupts_restore(ipl); |
return ENOENT; |
map: |
spinlock_unlock(&parea_lock); |
spinlock_lock(&TASK->lock); |
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, |
AS_AREA_ATTR_NONE, &phys_backend, &backend_data)) { |
if (!as_area_create(TASK->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE, |
&phys_backend, &backend_data)) { |
/* |
* The address space area could not have been created. |
* We report it using ENOMEM. |
187,24 → 169,28 |
* @param size Size of the enabled I/O space.. |
* |
* @return 0 on success, EPERM if the caller lacks capabilities to use this |
* syscall, ENOENT if there is no task matching the specified ID. |
* |
* syscall, ENOENT if there is no task matching the specified ID. |
*/ |
static int ddi_iospace_enable(task_id_t id, uintptr_t ioaddr, size_t size) |
{ |
ipl_t ipl; |
cap_t caps; |
task_t *t; |
int rc; |
/* |
* Make sure the caller is authorised to make this syscall. |
*/ |
cap_t caps = cap_get(TASK); |
caps = cap_get(TASK); |
if (!(caps & CAP_IO_MANAGER)) |
return EPERM; |
ipl_t ipl = interrupts_disable(); |
ipl = interrupts_disable(); |
spinlock_lock(&tasks_lock); |
task_t *task = task_find_by_id(id); |
t = task_find_by_id(id); |
if ((!task) || (!context_check(CONTEXT, task->context))) { |
if ((!t) || (!context_check(CONTEXT, t->context))) { |
/* |
* There is no task with the specified ID |
* or the task belongs to a different security |
214,16 → 200,15 |
interrupts_restore(ipl); |
return ENOENT; |
} |
/* Lock the task and release the lock protecting tasks_btree. */ |
spinlock_lock(&task->lock); |
spinlock_lock(&t->lock); |
spinlock_unlock(&tasks_lock); |
rc = ddi_iospace_enable_arch(t, ioaddr, size); |
int rc = ddi_iospace_enable_arch(task, ioaddr, size); |
spinlock_unlock(&task->lock); |
spinlock_unlock(&t->lock); |
interrupts_restore(ipl); |
return rc; |
} |
235,8 → 220,7 |
* @param flags Flags of newly mapped pages |
* |
* @return 0 on success, otherwise it returns error code found in errno.h |
* |
*/ |
*/ |
unative_t sys_physmem_map(unative_t phys_base, unative_t virt_base, |
unative_t pages, unative_t flags) |
{ |
250,15 → 234,16 |
* @param uspace_io_arg User space address of DDI argument structure. |
* |
* @return 0 on success, otherwise it returns error code found in errno.h |
* |
*/ |
*/ |
unative_t sys_iospace_enable(ddi_ioarg_t *uspace_io_arg) |
{ |
ddi_ioarg_t arg; |
int rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); |
int rc; |
rc = copy_from_uspace(&arg, uspace_io_arg, sizeof(ddi_ioarg_t)); |
if (rc != 0) |
return (unative_t) rc; |
return (unative_t) ddi_iospace_enable((task_id_t) arg.task_id, |
(uintptr_t) arg.ioaddr, (size_t) arg.size); |
} |
266,24 → 251,20 |
/** Disable or enable preemption. |
* |
* @param enable If non-zero, the preemption counter will be decremented, |
* leading to potential enabling of preemption. Otherwise |
* the preemption counter will be incremented, preventing |
* preemption from occurring. |
* leading to potential enabling of preemption. Otherwise the preemption |
* counter will be incremented, preventing preemption from occurring. |
* |
* @return Zero on success or EPERM if callers capabilities are not sufficient. |
* |
*/ |
*/ |
unative_t sys_preempt_control(int enable) |
{ |
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL) |
return EPERM; |
if (enable) |
preemption_enable(); |
else |
preemption_disable(); |
return 0; |
if (!cap_get(TASK) & CAP_PREEMPT_CONTROL) |
return EPERM; |
if (enable) |
preemption_enable(); |
else |
preemption_disable(); |
return 0; |
} |
/** @} |
/branches/dd/kernel/generic/src/cpu/cpu.c |
---|
64,10 → 64,10 |
cpus = (cpu_t *) malloc(sizeof(cpu_t) * config.cpu_count, |
FRAME_ATOMIC); |
if (!cpus) |
panic("Cannot allocate CPU structures."); |
panic("malloc/cpus"); |
/* initialize everything */ |
memsetb(cpus, sizeof(cpu_t) * config.cpu_count, 0); |
memsetb((uintptr_t) cpus, sizeof(cpu_t) * config.cpu_count, 0); |
for (i = 0; i < config.cpu_count; i++) { |
cpus[i].stack = (uint8_t *) frame_alloc(STACK_FRAMES, FRAME_KA | FRAME_ATOMIC); |
86,7 → 86,7 |
} |
#endif /* CONFIG_SMP */ |
CPU = &cpus[config.cpu_active - 1]; |
CPU = &cpus[config.cpu_active-1]; |
CPU->active = 1; |
CPU->tlb_active = 1; |
104,7 → 104,7 |
if (cpus[i].active) |
cpu_print_report(&cpus[i]); |
else |
printf("cpu%u: not active\n", i); |
printf("cpu%d: not active\n", i); |
} |
} |
/branches/dd/kernel/generic/src/sysinfo/sysinfo.c |
---|
163,8 → 163,7 |
i = 0; |
} |
} |
panic("Not reached."); |
panic("Not reached\n"); |
return NULL; |
} |
178,7 → 177,7 |
sysinfo_item_t *item = sysinfo_create_path(name, root); |
if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */ |
item->val.val = val; |
item->val.val=val; |
item->val_type = SYSINFO_VAL_VAL; |
} |
} |
193,7 → 192,7 |
sysinfo_item_t *item = sysinfo_create_path(name, root); |
if (item != NULL) { /* If in subsystem, unable to create or return so unable to set */ |
item->val.fn = fn; |
item->val.fn=fn; |
item->val_type = SYSINFO_VAL_FUNCTION; |
} |
} |
245,7 → 244,7 |
break; |
} |
printf("%s %s val:%" PRIun "(%" PRIxn ") sub:%s\n", root->name, vtype, val, |
printf("%s %s val:%d(%x) sub:%s\n", root->name, vtype, val, |
val, (root->subinfo_type == SYSINFO_SUBINFO_NONE) ? |
"NON" : ((root->subinfo_type == SYSINFO_SUBINFO_TABLE) ? |
"TAB" : "FUN")); |
282,15 → 281,10 |
return ret; |
} |
#define SYSINFO_MAX_LEN 1024 |
unative_t sys_sysinfo_valid(unative_t ptr, unative_t len) |
{ |
char *str; |
sysinfo_rettype_t ret = {0, 0}; |
if (len > SYSINFO_MAX_LEN) |
return ret.valid; |
str = malloc(len + 1, 0); |
ASSERT(str); |
305,9 → 299,6 |
{ |
char *str; |
sysinfo_rettype_t ret = {0, 0}; |
if (len > SYSINFO_MAX_LEN) |
return ret.val; |
str = malloc(len + 1, 0); |
ASSERT(str); |
/branches/dd/kernel/arch/ppc32/include/regutils.h |
---|
File deleted |
/branches/dd/kernel/arch/ppc32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
35,13 → 35,13 |
#ifndef KERN_ppc32_FRAME_H_ |
#define KERN_ppc32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/types.h> |
extern uintptr_t last_frame; |
/branches/dd/kernel/arch/ppc32/include/mm/page.h |
---|
40,6 → 40,8 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
120,7 → 122,7 |
/* Macros for querying the last-level PTEs. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->present != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((pte)->pfn << 12) |
#define PTE_WRITABLE_ARCH(pte) 1 |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
134,13 → 136,13 |
{ |
pte_t *p = &pt[i]; |
return (((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT) | |
((!p->present) << PAGE_PRESENT_SHIFT) | |
return ((1 << PAGE_CACHEABLE_SHIFT) | |
((!p->p) << PAGE_PRESENT_SHIFT) | |
(1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | |
(1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->global << PAGE_GLOBAL_SHIFT)); |
(p->g << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
147,9 → 149,8 |
{ |
pte_t *p = &pt[i]; |
p->page_cache_disable = !(flags & PAGE_CACHEABLE); |
p->present = !(flags & PAGE_NOT_PRESENT); |
p->global = (flags & PAGE_GLOBAL) != 0; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->valid = 1; |
} |
/branches/dd/kernel/arch/ppc32/include/mm/tlb.h |
---|
36,14 → 36,7 |
#define KERN_ppc32_TLB_H_ |
#include <arch/interrupt.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#define WIMG_GUARDED 0x01 |
#define WIMG_COHERENT 0x02 |
#define WIMG_NO_CACHE 0x04 |
#define WIMG_WRITETHRU 0x08 |
typedef struct { |
unsigned v : 1; /**< Valid */ |
unsigned vsid : 24; /**< Virtual Segment ID */ |
58,27 → 51,9 |
unsigned pp : 2; /**< Page protection */ |
} phte_t; |
typedef struct { |
unsigned v : 1; |
unsigned vsid : 24; |
unsigned reserved0 : 1; |
unsigned api : 6; |
} ptehi_t; |
typedef struct { |
unsigned rpn : 20; |
unsigned xpn : 3; |
unsigned reserved0 : 1; |
unsigned c : 1; |
unsigned wimg : 4; |
unsigned x : 1; |
unsigned pp : 2; |
} ptelo_t; |
extern void pht_refill(int n, istate_t *istate); |
extern bool pht_real_refill(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void pht_init(void); |
extern void pht_refill(int n, istate_t *istate); |
extern bool pht_refill_real(int n, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
extern void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) __attribute__ ((section("K_UNMAPPED_TEXT_START"))); |
#endif |
/branches/dd/kernel/arch/ppc32/include/types.h |
---|
35,6 → 35,10 |
#ifndef KERN_ppc32_TYPES_H_ |
#define KERN_ppc32_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
57,43 → 61,21 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "x" |
#define PRIs "u" |
#define PRIc "u" |
#define PRIi "u" |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
#define PRId16 "d" |
#define PRId32 "d" |
#define PRId64 "lld" |
#define PRIdn "d" |
#define PRIu8 "u" |
#define PRIu16 "u" |
#define PRIu32 "u" |
#define PRIu64 "llu" |
#define PRIun "u" |
#define PRIx8 "x" |
#define PRIx16 "x" |
#define PRIx32 "x" |
#define PRIx64 "llx" |
#define PRIxn "x" |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; /**< Present bit. */ |
unsigned page_write_through : 1; /**< Write thought caching. */ |
unsigned page_cache_disable : 1; /**< No caching. */ |
unsigned accessed : 1; /**< Accessed bit. */ |
unsigned global : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
unsigned p : 1; /**< Present bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
unsigned g : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
} pte_t; |
#endif |
/branches/dd/kernel/arch/ppc32/include/exception.h |
---|
36,7 → 36,6 |
#define KERN_ppc32_EXCEPTION_H_ |
#include <arch/types.h> |
#include <arch/regutils.h> |
typedef struct { |
uint32_t r0; |
75,7 → 74,6 |
uint32_t lr; |
uint32_t ctr; |
uint32_t xer; |
uint32_t dar; |
uint32_t r12; |
uint32_t sp; |
} istate_t; |
84,14 → 82,13 |
{ |
istate->pc = retaddr; |
} |
/** Return true if exception happened while in userspace */ |
#include <panic.h> |
static inline int istate_from_uspace(istate_t *istate) |
{ |
/* true if privilege level PR (copied from MSR) == 1 */ |
return (istate->srr1 & MSR_PR) != 0; |
panic("istate_from_uspace not yet implemented"); |
return 0; |
} |
static inline unative_t istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
/branches/dd/kernel/arch/ppc32/include/drivers/cuda.h |
---|
36,10 → 36,11 |
#define KERN_ppc32_CUDA_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
extern void cuda_init(devno_t devno, uintptr_t base, size_t size); |
extern int cuda_get_scancode(void); |
extern void cuda_grab(void); |
extern void cuda_release(void); |
#endif |
/branches/dd/kernel/arch/ppc32/include/asm/regname.h |
---|
211,19 → 211,15 |
#define dbat2l 541 |
#define dbat3u 542 |
#define dbat3l 543 |
#define tlbmiss 980 |
#define ptehi 981 |
#define ptelo 982 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_dr (1 << 4) |
#define msr_ir (1 << 5) |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
#define msr_pr (1 << 14) |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_sten (1 << 24) |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
/branches/dd/kernel/arch/ppc32/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/branches/dd/kernel/arch/ppc32/include/boot/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
35,24 → 35,21 |
#ifndef KERN_ppc32_BOOT_H_ |
#define KERN_ppc32_BOOT_H_ |
#define BOOT_OFFSET 0x8000 |
#define BOOT_OFFSET 0x8000 |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x1000 |
#define TEMP_STACK_SIZE 0x100 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#ifndef __ASM__ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
82,13 → 79,13 |
typedef struct { |
uintptr_t addr; |
unsigned int size; |
} macio_t; |
} keyboard_t; |
typedef struct { |
memmap_t memmap; |
taskmap_t taskmap; |
screen_t screen; |
macio_t macio; |
keyboard_t keyboard; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
/branches/dd/kernel/arch/ppc32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32 |
/** @addtogroup ppc32 |
* @{ |
*/ |
/** @file |
35,7 → 35,7 |
#ifndef KERN_ppc32_ARCH_H_ |
#define KERN_ppc32_ARCH_H_ |
extern void arch_pre_main(void); |
#include <arch/drivers/cuda.h> |
#endif |
/branches/dd/kernel/arch/ppc32/include/asm.h |
---|
36,7 → 36,6 |
#define KERN_ppc32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
/** Enable interrupts. |
150,36 → 149,6 |
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry); |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ppc32/include/barrier.h |
---|
42,47 → 42,6 |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
/* |
* The IMB sequence used here is valid for all possible cache models |
* on uniprocessor. SMP might require a different sequence. |
* See PowerPC Programming Environment for 32-Bit Microprocessors, |
* chapter 5.1.5.2 |
*/ |
static inline void smc_coherence(void *addr) |
{ |
asm volatile ( |
"dcbst 0, %0\n" |
"sync\n" |
"icbi 0, %0\n" |
"sync\n" |
"isync\n" |
:: "r" (addr) |
); |
} |
#define COHERENCE_INVAL_MIN 4 |
static inline void smc_coherence_block(void *addr, unsigned long len) |
{ |
unsigned long i; |
for (i = 0; i < len; i += COHERENCE_INVAL_MIN) { |
asm volatile ("dcbst 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ("sync"); |
for (i = 0; i < len; i += COHERENCE_INVAL_MIN) { |
asm volatile ("icbi 0, %0\n" :: "r" (addr + i)); |
} |
asm volatile ( |
"sync\n" |
"isync\n" |
); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ppc32/src/ppc32.c |
---|
45,25 → 45,21 |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/drivers/pic.h> |
#include <macros.h> |
#include <string.h> |
#define IRQ_COUNT 64 |
#define IRQ_COUNT 64 |
bootinfo_t bootinfo; |
/** Performs ppc32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo.taskmap.count; |
uint32_t i; |
for (i = 0; i < min3(bootinfo.taskmap.count, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
80,47 → 76,34 |
{ |
if (config.cpu_active == 1) { |
/* Initialize framebuffer */ |
if (bootinfo.screen.addr) { |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel."); |
} |
fb_properties_t prop = { |
.addr = bootinfo.screen.addr, |
.offset = 0, |
.x = bootinfo.screen.width, |
.y = bootinfo.screen.height, |
.scan = bootinfo.screen.scanline, |
.visual = visual, |
}; |
fb_init(&prop); |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
} |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual); |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
/* Initialize PIC */ |
pic_init(bootinfo.keyboard.addr, PAGE_SIZE); |
if (bootinfo.macio.addr) { |
/* Initialize PIC */ |
pic_init(bootinfo.macio.addr, PAGE_SIZE); |
/* Initialize I/O controller */ |
cuda_init(device_assign_devno(), |
bootinfo.macio.addr + 0x16000, 2 * PAGE_SIZE); |
} |
/* Initialize I/O controller */ |
cuda_init(device_assign_devno(), bootinfo.keyboard.addr + 0x16000, 2 * PAGE_SIZE); |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
145,13 → 128,11 |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE - SP_DELTA, |
(uintptr_t) kernel_uarg->uspace_entry); |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
while (true); |
for (;;) |
; |
} |
/** Acquire console back for kernel |
159,7 → 140,7 |
*/ |
void arch_grab_console(void) |
{ |
fb_redraw(); |
cuda_grab(); |
} |
/** Return console to userspace |
167,21 → 148,8 |
*/ |
void arch_release_console(void) |
{ |
cuda_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc32/src/mm/frame.c |
---|
74,7 → 74,7 |
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); |
} |
/* First is exception vector, second is 'implementation specific', |
third and fourth is reserved, other contain real mode code */ |
frame_mark_unavailable(0, 8); |
/branches/dd/kernel/arch/ppc32/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
47,16 → 47,13 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%" PRIs " bytes).", |
physaddr, size) |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), |
physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
/branches/dd/kernel/arch/ppc32/src/mm/tlb.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc32mm |
/** @addtogroup ppc32mm |
* @{ |
*/ |
/** @file |
35,23 → 35,12 |
#include <mm/tlb.h> |
#include <arch/mm/tlb.h> |
#include <arch/interrupt.h> |
#include <interrupt.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <print.h> |
#include <symtab.h> |
#include <macros.h> |
static unsigned int seed = 10; |
static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; |
#define TLB_FLUSH \ |
"tlbie %0\n" \ |
"addi %0, %0, 0x1000\n" |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
58,25 → 47,22 |
* The as->lock must be held on entry to this function |
* if lock is true. |
* |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* @return PTE on success, NULL otherwise. |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @return PTE on success, NULL otherwise. |
* |
*/ |
static pte_t * |
find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
istate_t *istate, int *pfrc) |
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
{ |
/* |
* Check if the mapping exists in page tables. |
*/ |
pte_t *pte = page_mapping_find(as, badvaddr); |
if ((pte) && (pte->present)) { |
if ((pte) && (pte->p)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
91,26 → 77,27 |
*/ |
page_table_unlock(as, lock); |
switch (rc = as_page_fault(badvaddr, access, istate)) { |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->present)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
default: |
panic("Unexpected rc (%d).", rc); |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
121,21 → 108,17 |
char *symbol = ""; |
char *sym2 = ""; |
char *str = get_symtab_entry(istate->pc); |
if (str) |
symbol = str; |
str = get_symtab_entry(istate->lr); |
if (str) |
sym2 = str; |
fault_if_from_uspace(istate, |
"PHT Refill Exception on %p.", badvaddr); |
panic("%p: PHT Refill Exception at %p (%s<-%s).", badvaddr, |
istate->pc, symbol, sym2); |
char *s = get_symtab_entry(istate->pc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
} |
static void pht_insert(const uintptr_t vaddr, const pte_t *pte) |
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
161,12 → 144,10 |
uint32_t i; |
bool found = false; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte[base + i].v) |
&& (phte[base + i].vsid == vsid) |
&& (phte[base + i].api == api) |
&& (phte[base + i].h == 0)) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { |
found = true; |
break; |
} |
173,25 → 154,13 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[base + i].v) { |
found = true; |
break; |
} |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte[base2 + i].v) |
&& (phte[base2 + i].vsid == vsid) |
&& (phte[base2 + i].api == api) |
&& (phte[base2 + i].h == 1)) { |
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
200,19 → 169,9 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
// TODO: A/C precedence groups |
i = page % 8; |
} |
if (!found) |
i = RANDI(seed) % 8; |
} |
phte[base + i].v = 1; |
219,106 → 178,23 |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pte->pfn; |
phte[base + i].rpn = pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].wimg = (pte->page_cache_disable ? WIMG_NO_CACHE : 0); |
phte[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Exception |
* |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(int n, istate_t *istate) |
static void pht_real_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
as_t *as; |
bool lock; |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
if (AS == NULL) { |
as = AS_KERNEL; |
lock = false; |
} else { |
as = AS; |
lock = true; |
} |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
badvaddr = istate->pc; |
page_table_lock(as, lock); |
pte = find_mapping_and_check(as, lock, badvaddr, |
PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
} |
} |
pte->accessed = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte); |
page_table_unlock(as, lock); |
return; |
fail: |
page_table_unlock(as, lock); |
pht_refill_fail(badvaddr, istate); |
} |
/** Process Instruction/Data Storage Exception in Real Mode |
* |
* @param n Exception vector number. |
* @param istate Interrupted register context. |
* |
*/ |
bool pht_refill_real(int n, istate_t *istate) |
{ |
uintptr_t badvaddr; |
if (n == VECTOR_DATA_STORAGE) |
badvaddr = istate->dar; |
else |
badvaddr = istate->pc; |
uint32_t physmem; |
asm volatile ( |
"mfsprg3 %0\n" |
: "=r" (physmem) |
); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return false; |
uint32_t page = (badvaddr >> 12) & 0xffff; |
uint32_t api = (badvaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (badvaddr) |
: "r" (vaddr) |
); |
uint32_t sdr1; |
326,7 → 202,7 |
"mfsdr1 %0\n" |
: "=r" (sdr1) |
); |
phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); |
phte_t *phte_physical = (phte_t *) (sdr1 & 0xffff0000); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
335,12 → 211,10 |
uint32_t i; |
bool found = false; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base + i].v) |
&& (phte_real[base + i].vsid == vsid) |
&& (phte_real[base + i].api == api) |
&& (phte_real[base + i].h == 0)) { |
if ((!phte_physical[base + i].v) || ((phte_physical[base + i].vsid == vsid) && (phte_physical[base + i].api == api))) { |
found = true; |
break; |
} |
347,25 → 221,13 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base + i].v) { |
found = true; |
break; |
} |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find colliding PTE in PTEG */ |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((phte_real[base2 + i].v) |
&& (phte_real[base2 + i].vsid == vsid) |
&& (phte_real[base2 + i].api == api) |
&& (phte_real[base2 + i].h == 1)) { |
if ((!phte_physical[base2 + i].v) || ((phte_physical[base2 + i].vsid == vsid) && (phte_physical[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
374,48 → 236,102 |
} |
if (!found) { |
/* Find unused PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if (!phte_real[base2 + i].v) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
// TODO: A/C precedence groups |
i = page % 8; |
} |
} |
phte_physical[base + i].v = 1; |
phte_physical[base + i].vsid = vsid; |
phte_physical[base + i].h = h; |
phte_physical[base + i].api = api; |
phte_physical[base + i].rpn = pfn; |
phte_physical[base + i].r = 0; |
phte_physical[base + i].c = 0; |
phte_physical[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Interrupt |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(int n, istate_t *istate) |
{ |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
as_t *as; |
bool lock; |
if (AS == NULL) { |
as = AS_KERNEL; |
lock = false; |
} else { |
as = AS; |
lock = true; |
} |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
if (!found) { |
/* Use secondary hash to avoid collisions |
with usual PHT refill handler. */ |
i = RANDI(seed_real) % 8; |
base = base2; |
h = 1; |
page_table_lock(as, lock); |
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfrc); |
} |
} |
phte_real[base + i].v = 1; |
phte_real[base + i].vsid = vsid; |
phte_real[base + i].h = h; |
phte_real[base + i].api = api; |
phte_real[base + i].rpn = KA2PA(badvaddr) >> 12; |
phte_real[base + i].r = 0; |
phte_real[base + i].c = 0; |
phte_real[base + i].wimg = 0; |
phte_real[base + i].pp = 2; // FIXME |
pte->a = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte->pfn); |
return true; |
page_table_unlock(as, lock); |
return; |
fail: |
page_table_unlock(as, lock); |
pht_refill_fail(badvaddr, istate); |
} |
/** Process ITLB/DTLB Miss Exception in Real Mode |
/** Process Instruction/Data Storage Interrupt in Real Mode |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted register context. |
* |
*/ |
void tlb_refill_real(int n, uint32_t tlbmiss, ptehi_t ptehi, ptelo_t ptelo, istate_t *istate) |
bool pht_real_refill(int n, istate_t *istate) |
{ |
uint32_t badvaddr = tlbmiss & 0xfffffffc; |
uintptr_t badvaddr; |
if (n == VECTOR_DATA_STORAGE) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
uint32_t physmem; |
asm volatile ( |
"mfsprg3 %0\n" |
422,23 → 338,12 |
: "=r" (physmem) |
); |
if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) |
return; // FIXME |
if ((badvaddr >= PA2KA(0)) && (badvaddr < PA2KA(physmem))) { |
pht_real_insert(badvaddr, KA2PA(badvaddr) >> 12); |
return true; |
} |
ptelo.rpn = KA2PA(badvaddr) >> 12; |
ptelo.wimg = 0; |
ptelo.pp = 2; // FIXME |
uint32_t index = 0; |
asm volatile ( |
"mtspr 981, %0\n" |
"mtspr 982, %1\n" |
"tlbld %2\n" |
"tlbli %2\n" |
: "=r" (index) |
: "r" (ptehi), |
"r" (ptelo) |
); |
return false; |
} |
450,87 → 355,9 |
void tlb_invalidate_all(void) |
{ |
uint32_t index; |
asm volatile ( |
"li %0, 0\n" |
"sync\n" |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
TLB_FLUSH |
"eieio\n" |
"tlbia\n" |
"tlbsync\n" |
"sync\n" |
: "=r" (index) |
); |
} |
546,8 → 373,7 |
uint32_t i; |
for (i = 0; i < 8192; i++) { |
if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && |
(phte[i].vsid < ((asid << 4) + 16))) |
if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && (phte[i].vsid < ((asid << 4) + 16))) |
phte[i].v = 0; |
} |
tlb_invalidate_all(); |
581,11 → 407,7 |
} \ |
} else \ |
length = 0; \ |
printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ |
sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ |
lower & 0xffff0000, length, mask, \ |
((upper >> 1) & 1) ? " supervisor" : "", \ |
(upper & 1) ? " user" : ""); |
printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, lower & 0xffff0000, length, mask, ((upper >> 1) & 1) ? " supervisor" : "", (upper & 1) ? " user" : ""); |
void tlb_print(void) |
599,10 → 421,7 |
: "=r" (vsid) |
: "r" (sr << 28) |
); |
printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, |
sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, |
((vsid >> 30) & 1) ? " supervisor" : "", |
((vsid >> 29) & 1) ? " user" : ""); |
printf("vsid[%d]: VSID=%.*p (ASID=%d)%s%s\n", sr, sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, ((vsid >> 30) & 1) ? " supervisor" : "", ((vsid >> 29) & 1) ? " user" : ""); |
} |
uint32_t upper; |
/branches/dd/kernel/arch/ppc32/src/drivers/cuda.c |
---|
33,6 → 33,7 |
*/ |
#include <arch/drivers/cuda.h> |
#include <ipc/irq.h> |
#include <arch/asm.h> |
#include <console/console.h> |
#include <console/chardev.h> |
235,38 → 236,64 |
int cuda_get_scancode(void) |
{ |
if (cuda) { |
uint8_t kind; |
uint8_t data[4]; |
receive_packet(&kind, 4, data); |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
} |
uint8_t kind; |
uint8_t data[4]; |
receive_packet(&kind, 4, data); |
if ((kind == PACKET_ADB) && (data[0] == 0x40) && (data[1] == 0x2c)) |
return data[2]; |
return -1; |
} |
static void cuda_irq_handler(irq_t *irq) |
static void cuda_irq_handler(irq_t *irq, void *arg, ...) |
{ |
int scan_code = cuda_get_scancode(); |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
int scan_code = cuda_get_scancode(); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
if (scan_code != -1) { |
uint8_t scancode = (uint8_t) scan_code; |
if ((scancode & 0x80) != 0x80) |
chardev_push_character(&kbrd, lchars[scancode & 0x7f]); |
} |
} |
} |
static irq_ownership_t cuda_claim(irq_t *irq) |
static irq_ownership_t cuda_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Initialize keyboard and service interrupts using kernel routine */ |
void cuda_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
cuda_irq.notif_cfg.notify = false; |
spinlock_unlock(&cuda_irq.lock); |
interrupts_restore(ipl); |
} |
/** Resume the former interrupt vector */ |
void cuda_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&cuda_irq.lock); |
if (cuda_irq.notif_cfg.answerbox) |
cuda_irq.notif_cfg.notify = true; |
spinlock_unlock(&cuda_irq.unlock); |
interrupts_restore(ipl); |
} |
void cuda_init(devno_t devno, uintptr_t base, size_t size) |
{ |
cuda = (uint8_t *) hw_map(base, size); |
cuda = (uint8_t *) hw_map(base, size); |
chardev_initialize("cuda_kbd", &kbrd, &ops); |
stdin = &kbrd; |
279,7 → 306,7 |
irq_register(&cuda_irq); |
pic_enable_interrupt(CUDA_IRQ); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, CUDA_IRQ); |
318,9 → 345,7 |
} |
void arch_reboot(void) { |
if (cuda) |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
send_packet(PACKET_CUDA, 1, CUDA_RESET); |
asm volatile ( |
"b 0\n" |
); |
/branches/dd/kernel/arch/ppc32/src/drivers/pic.c |
---|
38,7 → 38,7 |
#include <byteorder.h> |
#include <bitops.h> |
static volatile uint32_t *pic = NULL; |
static volatile uint32_t *pic; |
void pic_init(uintptr_t base, size_t size) |
{ |
47,11 → 47,10 |
void pic_enable_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
} |
} |
58,39 → 57,34 |
void pic_disable_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
else |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
} |
} |
void pic_ack_interrupt(int intnum) |
{ |
if (pic) { |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
/** Return number of pending interrupt */ |
int pic_get_pending(void) |
{ |
if (pic) { |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
} |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
return -1; |
} |
/branches/dd/kernel/arch/ppc32/src/interrupt.c |
---|
73,7 → 73,7 |
ack = true; |
} |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
80,7 → 80,7 |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (inum=%d)\n", CPU->id, inum); |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
92,8 → 92,8 |
static void exception_decrementer(int n, istate_t *istate) |
{ |
clock(); |
start_decrementer(); |
clock(); |
} |
/branches/dd/kernel/arch/ppc32/src/exception.S |
---|
60,7 → 60,7 |
2: |
subi sp, sp, 164 |
subi sp, sp, 160 |
stw r0, 8(sp) |
stw r2, 12(sp) |
stw r3, 16(sp) |
109,14 → 109,11 |
mfxer r12 |
stw r12, 148(sp) |
mfdar r12 |
mfsprg1 r12 |
stw r12, 152(sp) |
mfsprg1 r12 |
mfsprg2 r12 |
stw r12, 156(sp) |
mfsprg2 r12 |
stw r12, 160(sp) |
.endm |
.org 0x100 |
140,7 → 137,16 |
exc_data_storage: |
CONTEXT_STORE |
b data_storage |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
147,8 → 153,17 |
exc_instruction_storage: |
CONTEXT_STORE |
b instruction_storage |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_real_refill |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
208,7 → 223,7 |
.org 0xc00 |
.global exc_syscall |
exc_syscall: |
CONTEXT_STORE |
CONTEXT_STORE |
b jump_to_kernel_syscall |
220,63 → 235,7 |
li r3, 12 |
b jump_to_kernel |
.org 0x1000 |
.global exc_itlb_miss |
exc_itlb_miss: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1100 |
.global exc_dtlb_miss_load |
exc_dtlb_miss_load: |
CONTEXT_STORE |
b tlb_miss |
.org 0x1200 |
.global exc_dtlb_miss_store |
exc_dtlb_miss_store: |
CONTEXT_STORE |
b tlb_miss |
.org 0x4000 |
data_storage: |
li r3, 2 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 2 |
b jump_to_kernel |
instruction_storage: |
li r3, 3 |
mr r4, sp |
addi r4, r4, 8 |
bl pht_refill_real |
cmpwi r3, 0 |
bne iret_real |
li r3, 3 |
b jump_to_kernel |
tlb_miss: |
li r3, 16 |
mfspr r4, tlbmiss |
mfspr r5, ptehi |
mfspr r6, ptelo |
mr r7, sp |
addi r7, r7, 20 |
bl tlb_refill_real |
b iret_real |
jump_to_kernel: |
lis r12, iret@ha |
addi r12, r12, iret@l |
313,6 → 272,7 |
rfi |
iret_real: |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r3, 16(sp) |
362,7 → 322,7 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
/branches/dd/kernel/arch/ppc32/src/asm.S |
---|
65,10 → 65,6 |
# set stack |
mr sp, r4 |
# %r6 is defined to hold pcb_ptr - set it to 0 |
xor r6, r6, r6 |
# jump to userspace |
131,8 → 127,8 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
197,13 → 193,53 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 156(sp) |
lwz sp, 160(sp) |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
memsetb: |
b _memsetb |
rlwimi r5, r5, 8, 16, 23 |
rlwimi r5, r5, 16, 0, 15 |
addi r14, r3, -4 |
cmplwi 0, r4, 4 |
blt 7f |
stwu r5, 4(r14) |
beqlr |
andi. r15, r14, 3 |
add r4, r15, r4 |
subf r14, r15, r14 |
srwi r15, r4, 2 |
mtctr r15 |
bdz 6f |
1: |
stwu r5, 4(r14) |
bdnz 1b |
6: |
andi. r4, r4, 3 |
7: |
cmpwi 0, r4, 0 |
beqlr |
mtctr r4 |
addi r6, r6, 3 |
8: |
stbu r5, 1(r14) |
bdnz 8b |
blr |
memcpy: |
memcpy_from_uspace: |
272,6 → 308,4 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
# return zero, failure |
xor r3, r3, r3 |
blr |
b memcpy_from_uspace_failover_address |
/branches/dd/kernel/arch/ppc32/src/boot/boot.S |
---|
33,7 → 33,7 |
.global kernel_image_start |
kernel_image_start: |
# load temporal kernel stack |
lis sp, kernel_stack@ha |
52,7 → 52,7 |
beq bootinfo_end |
addis r3, r3, 0x8000 |
lis r31, bootinfo@ha |
addi r31, r31, bootinfo@l # r31 = bootinfo |
/branches/dd/kernel/arch/ppc32/Makefile.inc |
---|
33,7 → 33,7 |
BFD_ARCH = powerpc:common |
BFD = binary |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc |
TOOLCHAIN_DIR = /usr/local/ppc |
GCC_CFLAGS += -mcpu=powerpc -msoft-float -m32 |
AFLAGS += -a32 |
41,22 → 41,44 |
DEFS += -D__32_BITS__ |
## Own configuration directives |
# |
CONFIG_FB = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/debug/panic.s \ |
arch/$(KARCH)/src/fpu_context.S \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/ppc32.c \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/exception.S \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/cuda.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/drivers/pic.c |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/fpu_context.S \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/ppc32.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/exception.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/cuda.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/drivers/pic.c |
/branches/dd/kernel/arch/ppc32/_link.ld.in |
---|
1,11 → 1,11 |
/** PPC32 linker script |
* |
* umapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* |
*/ |
27,7 → 27,7 |
unmapped_kdata_start = .; |
} |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
37,22 → 37,22 |
*(K_DATA_START); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
} |
/branches/dd/kernel/arch/ppc64/include/context_offset.h |
---|
0,0 → 1,132 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_ppc64_CONTEXT_OFFSET_H_ |
#define KERN_ppc64_CONTEXT_OFFSET_H_ |
#define OFFSET_SP 0x0 |
#define OFFSET_PC 0x8 |
#define OFFSET_R2 0x10 |
#define OFFSET_R13 0x18 |
#define OFFSET_R14 0x20 |
#define OFFSET_R15 0x28 |
#define OFFSET_R16 0x30 |
#define OFFSET_R17 0x38 |
#define OFFSET_R18 0x40 |
#define OFFSET_R19 0x48 |
#define OFFSET_R20 0x50 |
#define OFFSET_R21 0x58 |
#define OFFSET_R22 0x60 |
#define OFFSET_R23 0x68 |
#define OFFSET_R24 0x70 |
#define OFFSET_R25 0x78 |
#define OFFSET_R26 0x80 |
#define OFFSET_R27 0x88 |
#define OFFSET_R28 0x90 |
#define OFFSET_R29 0x98 |
#define OFFSET_R30 0xa0 |
#define OFFSET_R31 0xa8 |
#define OFFSET_CR 0xb0 |
#define OFFSET_FR14 0x0 |
#define OFFSET_FR15 0x8 |
#define OFFSET_FR16 0x10 |
#define OFFSET_FR17 0x18 |
#define OFFSET_FR18 0x20 |
#define OFFSET_FR19 0x28 |
#define OFFSET_FR20 0x30 |
#define OFFSET_FR21 0x38 |
#define OFFSET_FR22 0x40 |
#define OFFSET_FR23 0x48 |
#define OFFSET_FR24 0x50 |
#define OFFSET_FR25 0x58 |
#define OFFSET_FR26 0x60 |
#define OFFSET_FR27 0x68 |
#define OFFSET_FR28 0x70 |
#define OFFSET_FR29 0x78 |
#define OFFSET_FR30 0x80 |
#define OFFSET_FR31 0x88 |
#define OFFSET_FPSCR 0x90 |
#ifdef __ASM__ |
# include <arch/asm/regname.h> |
# ctx: address of the structure with saved context |
.macro CONTEXT_SAVE_ARCH_CORE ctx:req |
stw sp, OFFSET_SP(\ctx) |
stw r2, OFFSET_R2(\ctx) |
stw r13, OFFSET_R13(\ctx) |
stw r14, OFFSET_R14(\ctx) |
stw r15, OFFSET_R15(\ctx) |
stw r16, OFFSET_R16(\ctx) |
stw r17, OFFSET_R17(\ctx) |
stw r18, OFFSET_R18(\ctx) |
stw r19, OFFSET_R19(\ctx) |
stw r20, OFFSET_R20(\ctx) |
stw r21, OFFSET_R21(\ctx) |
stw r22, OFFSET_R22(\ctx) |
stw r23, OFFSET_R23(\ctx) |
stw r24, OFFSET_R24(\ctx) |
stw r25, OFFSET_R25(\ctx) |
stw r26, OFFSET_R26(\ctx) |
stw r27, OFFSET_R27(\ctx) |
stw r28, OFFSET_R28(\ctx) |
stw r29, OFFSET_R29(\ctx) |
stw r30, OFFSET_R30(\ctx) |
stw r31, OFFSET_R31(\ctx) |
.endm |
# ctx: address of the structure with saved context |
.macro CONTEXT_RESTORE_ARCH_CORE ctx:req |
lwz sp, OFFSET_SP(\ctx) |
lwz r2, OFFSET_R2(\ctx) |
lwz r13, OFFSET_R13(\ctx) |
lwz r14, OFFSET_R14(\ctx) |
lwz r15, OFFSET_R15(\ctx) |
lwz r16, OFFSET_R16(\ctx) |
lwz r17, OFFSET_R17(\ctx) |
lwz r18, OFFSET_R18(\ctx) |
lwz r19, OFFSET_R19(\ctx) |
lwz r20, OFFSET_R20(\ctx) |
lwz r21, OFFSET_R21(\ctx) |
lwz r22, OFFSET_R22(\ctx) |
lwz r23, OFFSET_R23(\ctx) |
lwz r24, OFFSET_R24(\ctx) |
lwz r25, OFFSET_R25(\ctx) |
lwz r26, OFFSET_R26(\ctx) |
lwz r27, OFFSET_R27(\ctx) |
lwz r28, OFFSET_R28(\ctx) |
lwz r29, OFFSET_R29(\ctx) |
lwz r30, OFFSET_R30(\ctx) |
lwz r31, OFFSET_R31(\ctx) |
.endm |
#endif /* __ASM__ */ |
#endif |
/branches/dd/kernel/arch/ppc64/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BYTEORDER_H_ |
#define KERN_ppc64_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/mm/frame.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FRAME_H_ |
#define KERN_ppc64_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/mm/page.h |
---|
0,0 → 1,186 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_PAGE_H_ |
#define KERN_ppc64_PAGE_H_ |
#include <arch/mm/frame.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
#else |
# define KA2PA(x) ((x) - 0x80000000) |
# define PA2KA(x) ((x) + 0x80000000) |
#endif |
/* |
* Implementation of generic 4-level page table interface, |
* the hardware Page Hash Table is used as cache. |
* |
* Page table layout: |
* - 32-bit virtual addressess |
* - Offset is 12 bits => pages are 4K long |
* - PTL0 has 1024 entries (10 bits) |
* - PTL1 is not used |
* - PTL2 is not used |
* - PLT3 has 1024 entries (10 bits) |
*/ |
/* Number of entries in each level. */ |
#define PTL0_ENTRIES_ARCH 1024 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
/* Sizes of page tables in each level. */ |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
/* Macros calculating indices into page tables in each level. */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
/* Get PTE address accessors for each level. */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
(((pte_t *) (ptl0))[(i)].pfn << 12) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
(((pte_t *) (ptl3))[(i)].pfn << 12) |
/* Set PTE address accessors for each level. */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
(((pte_t *) (ptl0))[(i)].pfn = (a) >> 12) |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
(((pte_t *) (ptl3))[(i)].pfn = (a) >> 12) |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Macros for querying the last-level PTEs. */ |
#define PTE_VALID_ARCH(pte) (*((uint32_t *) (pte)) != 0) |
#define PTE_PRESENT_ARCH(pte) ((pte)->p != 0) |
#define PTE_GET_FRAME_ARCH(pte) ((uintptr_t) ((pte)->pfn << 12)) |
#define PTE_WRITABLE_ARCH(pte) 1 |
#define PTE_EXECUTABLE_ARCH(pte) 1 |
#ifndef __ASM__ |
#include <mm/mm.h> |
#include <arch/interrupt.h> |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return ((1 << PAGE_CACHEABLE_SHIFT) | |
((!p->p) << PAGE_PRESENT_SHIFT) | |
(1 << PAGE_USER_SHIFT) | |
(1 << PAGE_READ_SHIFT) | |
(1 << PAGE_WRITE_SHIFT) | |
(1 << PAGE_EXEC_SHIFT) | |
(p->g << PAGE_GLOBAL_SHIFT)); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t *p = &pt[i]; |
p->p = !(flags & PAGE_NOT_PRESENT); |
p->g = (flags & PAGE_GLOBAL) != 0; |
p->valid = 1; |
} |
extern void page_arch_init(void); |
#define PHT_BITS 16 |
#define PHT_ORDER 4 |
typedef struct { |
unsigned v : 1; /**< Valid */ |
unsigned vsid : 24; /**< Virtual Segment ID */ |
unsigned h : 1; /**< Primary/secondary hash */ |
unsigned api : 6; /**< Abbreviated Page Index */ |
unsigned rpn : 20; /**< Real Page Number */ |
unsigned reserved0 : 3; |
unsigned r : 1; /**< Reference */ |
unsigned c : 1; /**< Change */ |
unsigned wimg : 4; /**< Access control */ |
unsigned reserved1 : 1; |
unsigned pp : 2; /**< Page protection */ |
} phte_t; |
extern void pht_refill(bool data, istate_t *istate); |
extern void pht_init(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/mm/as.h |
---|
0,0 → 1,64 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_AS_H_ |
#define KERN_ppc64_AS_H_ |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x80000000) |
#define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffff) |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (0x7fffffff - (PAGE_SIZE - 1)) |
typedef struct { |
} as_arch_t; |
#include <genarch/mm/as_pt.h> |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
extern void as_arch_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/mm/asid.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ASID_H_ |
#define KERN_ppc64_ASID_H_ |
typedef int asid_t; |
#define ASID_MAX_ARCH 3 |
#define asid_get() (ASID_START+1) |
#define asid_put(asid) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/mm/tlb.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TLB_H_ |
#define KERN_ppc64_TLB_H_ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/types.h |
---|
0,0 → 1,84 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TYPES_H_ |
#define KERN_ppc64_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
typedef signed long int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long uint64_t; |
typedef uint64_t size_t; |
typedef uint64_t count_t; |
typedef uint64_t index_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t pfn_t; |
typedef uint64_t ipl_t; |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
/** Page Table Entry. */ |
typedef struct { |
unsigned p : 1; /**< Present bit. */ |
unsigned a : 1; /**< Accessed bit. */ |
unsigned g : 1; /**< Global bit. */ |
unsigned valid : 1; /**< Valid content even if not present. */ |
unsigned pfn : 20; /**< Physical frame number. */ |
} pte_t; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/exception.h |
---|
0,0 → 1,100 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_EXCEPTION_H_ |
#define KERN_ppc64_EXCEPTION_H_ |
#include <arch/types.h> |
typedef struct { |
uint64_t r0; |
uint64_t r2; |
uint64_t r3; |
uint64_t r4; |
uint64_t r5; |
uint64_t r6; |
uint64_t r7; |
uint64_t r8; |
uint64_t r9; |
uint64_t r10; |
uint64_t r11; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
uint64_t pc; |
uint64_t srr1; |
uint64_t lr; |
uint64_t ctr; |
uint64_t xer; |
uint64_t r12; |
uint64_t sp; |
} istate_t; |
static inline void istate_set_retaddr(istate_t *istate, uintptr_t retaddr) |
{ |
istate->pc = retaddr; |
} |
/** Return true if exception happened while in userspace */ |
#include <panic.h> |
static inline int istate_from_uspace(istate_t *istate) |
{ |
panic("istate_from_uspace not yet implemented"); |
return 0; |
} |
static inline unative_t istate_get_pc(istate_t *istate) |
{ |
return istate->pc; |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/cpu.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CPU_H_ |
#define KERN_ppc64_CPU_H_ |
#include <arch/asm.h> |
typedef struct { |
int version; |
int revision; |
} cpu_arch_t; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/drivers/pic.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_PIC_H_ |
#define KERN_ppc64_PIC_H_ |
#include <arch/types.h> |
#define PIC_PENDING_LOW 8 |
#define PIC_PENDING_HIGH 4 |
#define PIC_MASK_LOW 9 |
#define PIC_MASK_HIGH 5 |
#define PIC_ACK_LOW 10 |
#define PIC_ACK_HIGH 6 |
void pic_init(uintptr_t base, size_t size); |
void pic_enable_interrupt(int intnum); |
void pic_disable_interrupt(int intnum); |
void pic_ack_interrupt(int intnum); |
int pic_get_pending(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/fpu_context.h |
---|
0,0 → 1,67 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FPU_CONTEXT_H_ |
#define KERN_ppc64_FPU_CONTEXT_H_ |
#ifndef KERN_ppc64_TYPES_H_ |
# include <arch/types.h> |
#endif |
typedef struct { |
uint64_t fr14; |
uint64_t fr15; |
uint64_t fr16; |
uint64_t fr17; |
uint64_t fr18; |
uint64_t fr19; |
uint64_t fr20; |
uint64_t fr21; |
uint64_t fr22; |
uint64_t fr23; |
uint64_t fr24; |
uint64_t fr25; |
uint64_t fr26; |
uint64_t fr27; |
uint64_t fr28; |
uint64_t fr29; |
uint64_t fr30; |
uint64_t fr31; |
uint32_t fpscr; |
} __attribute__ ((packed)) fpu_context_t; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/context.h |
---|
0,0 → 1,75 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CONTEXT_H_ |
#define KERN_ppc64_CONTEXT_H_ |
#include <arch/types.h> |
#define SP_DELTA 16 |
typedef struct { |
uintptr_t sp; |
uintptr_t pc; |
uint64_t r2; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
ipl_t ipl; |
} __attribute__ ((packed)) context_t; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/cpuid.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CPUID_H_ |
#define KERN_ppc64_CPUID_H_ |
#include <arch/types.h> |
typedef struct { |
uint16_t version; |
uint16_t revision; |
} __attribute__ ((packed)) cpu_info_t; |
static inline void cpu_version(cpu_info_t *info) |
{ |
asm volatile ( |
"mfpvr %0\n" |
: "=r" (*info) |
); |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/asm/regname.h |
---|
0,0 → 1,215 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_REGNAME_H_ |
#define KERN_ppc64_REGNAME_H_ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
#define cr1 1 |
#define cr2 2 |
#define cr3 3 |
#define cr4 4 |
#define cr5 5 |
#define cr6 6 |
#define cr7 7 |
/* General Purpose Registers (GPRs) */ |
#define r0 0 |
#define r1 1 |
#define r2 2 |
#define r3 3 |
#define r4 4 |
#define r5 5 |
#define r6 6 |
#define r7 7 |
#define r8 8 |
#define r9 9 |
#define r10 10 |
#define r11 11 |
#define r12 12 |
#define r13 13 |
#define r14 14 |
#define r15 15 |
#define r16 16 |
#define r17 17 |
#define r18 18 |
#define r19 19 |
#define r20 20 |
#define r21 21 |
#define r22 22 |
#define r23 23 |
#define r24 24 |
#define r25 25 |
#define r26 26 |
#define r27 27 |
#define r28 28 |
#define r29 29 |
#define r30 30 |
#define r31 31 |
/* GPR Aliases */ |
#define sp 1 |
/* Floating Point Registers (FPRs) */ |
#define fr0 0 |
#define fr1 1 |
#define fr2 2 |
#define fr3 3 |
#define fr4 4 |
#define fr5 5 |
#define fr6 6 |
#define fr7 7 |
#define fr8 8 |
#define fr9 9 |
#define fr10 10 |
#define fr11 11 |
#define fr12 12 |
#define fr13 13 |
#define fr14 14 |
#define fr15 15 |
#define fr16 16 |
#define fr17 17 |
#define fr18 18 |
#define fr19 19 |
#define fr20 20 |
#define fr21 21 |
#define fr22 22 |
#define fr23 23 |
#define fr24 24 |
#define fr25 25 |
#define fr26 26 |
#define fr27 27 |
#define fr28 28 |
#define fr29 29 |
#define fr30 30 |
#define fr31 31 |
#define vr0 0 |
#define vr1 1 |
#define vr2 2 |
#define vr3 3 |
#define vr4 4 |
#define vr5 5 |
#define vr6 6 |
#define vr7 7 |
#define vr8 8 |
#define vr9 9 |
#define vr10 10 |
#define vr11 11 |
#define vr12 12 |
#define vr13 13 |
#define vr14 14 |
#define vr15 15 |
#define vr16 16 |
#define vr17 17 |
#define vr18 18 |
#define vr19 19 |
#define vr20 20 |
#define vr21 21 |
#define vr22 22 |
#define vr23 23 |
#define vr24 24 |
#define vr25 25 |
#define vr26 26 |
#define vr27 27 |
#define vr28 28 |
#define vr29 29 |
#define vr30 30 |
#define vr31 31 |
#define evr0 0 |
#define evr1 1 |
#define evr2 2 |
#define evr3 3 |
#define evr4 4 |
#define evr5 5 |
#define evr6 6 |
#define evr7 7 |
#define evr8 8 |
#define evr9 9 |
#define evr10 10 |
#define evr11 11 |
#define evr12 12 |
#define evr13 13 |
#define evr14 14 |
#define evr15 15 |
#define evr16 16 |
#define evr17 17 |
#define evr18 18 |
#define evr19 19 |
#define evr20 20 |
#define evr21 21 |
#define evr22 22 |
#define evr23 23 |
#define evr24 24 |
#define evr25 25 |
#define evr26 26 |
#define evr27 27 |
#define evr28 28 |
#define evr29 29 |
#define evr30 30 |
#define evr31 31 |
/* Special Purpose Registers (SPRs) */ |
#define xer 1 |
#define lr 8 |
#define ctr 9 |
#define dec 22 |
#define sdr1 25 |
#define srr0 26 |
#define srr1 27 |
#define sprg0 272 |
#define sprg1 273 |
#define sprg2 274 |
#define sprg3 275 |
#define prv 287 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
#define msr_pr (1 << 14) |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
#define hid0_dci (1 << 10) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/interrupt.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64interrupt |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_INTERRUPT_H_ |
#define KERN_ppc64_INTERRUPT_H_ |
#include <arch/exception.h> |
#define IVT_ITEMS 16 |
#define IVT_FIRST 0 |
#define VECTOR_DATA_STORAGE 2 |
#define VECTOR_INSTRUCTION_STORAGE 3 |
#define VECTOR_EXTERNAL 4 |
#define VECTOR_DECREMENTER 8 |
extern void start_decrementer(void); |
extern void interrupt_init(void); |
extern void extint_handler(int n, istate_t *istate); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/cycle.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_CYCLE_H_ |
#define KERN_ppc64_CYCLE_H_ |
static inline uint64_t get_cycle(void) |
{ |
return 0; |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/elf.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2006 Sergey Bondari |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ELF_H_ |
#define KERN_ppc64_ELF_H_ |
#define ELF_MACHINE EM_PPC64 |
#define ELF_DATA_ENCODING ELFDATA2MSB |
#define ELF_CLASS ELFCLASS32 |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/memstr.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Sergey Bondari |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_MEMSTR_H_ |
#define KERN_ppc64_MEMSTR_H_ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/arg.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ARG_H_ |
#define KERN_ppc64_ARG_H_ |
#include <stdarg.h> |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/atomic.h |
---|
0,0 → 1,97 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ATOMIC_H_ |
#define KERN_ppc64_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, 1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc" |
); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, -1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc" |
); |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count - 1; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count + 1; |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count; |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/boot/boot.h |
---|
0,0 → 1,92 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BOOT_H_ |
#define KERN_ppc64_BOOT_H_ |
#define BOOT_OFFSET 0x4000 |
/* Temporary stack size for boot process */ |
#define TEMP_STACK_SIZE 0x100 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#ifndef __ASM__ |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint64_t size; |
} utask_t; |
typedef struct { |
uint32_t count; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
uintptr_t start; |
uint64_t size; |
} memzone_t; |
typedef struct { |
uint64_t total; |
uint32_t count; |
memzone_t zones[MEMMAP_MAX_RECORDS]; |
} memmap_t; |
typedef struct { |
uintptr_t addr; |
unsigned int width; |
unsigned int height; |
unsigned int bpp; |
unsigned int scanline; |
} screen_t; |
typedef struct { |
taskmap_t taskmap; |
memmap_t memmap; |
screen_t screen; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/arch.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ARCH_H_ |
#define KERN_ppc64_ARCH_H_ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/proc/task.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_TASK_H_ |
#define KERN_ppc64_TASK_H_ |
typedef struct { |
} task_arch_t; |
#define task_create_arch(t) |
#define task_destroy_arch(t) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/proc/thread.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_THREAD_H_ |
#define KERN_ppc64_THREAD_H_ |
typedef struct { |
} thread_arch_t; |
#define thr_constructor_arch(t) |
#define thr_destructor_arch(t) |
#define thread_create_arch(t) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/asm.h |
---|
0,0 → 1,161 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_ASM_H_ |
#define KERN_ppc64_ASM_H_ |
#include <arch/types.h> |
#include <config.h> |
/** Enable interrupts. |
* |
* Enable interrupts and return previous |
* value of EE. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
ipl_t v; |
ipl_t tmp; |
asm volatile ( |
"mfmsr %0\n" |
"mfmsr %1\n" |
"ori %1, %1, 1 << 15\n" |
"mtmsr %1\n" |
: "=r" (v), "=r" (tmp) |
); |
return v; |
} |
/** Disable interrupts. |
* |
* Disable interrupts and return previous |
* value of EE. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
ipl_t v; |
ipl_t tmp; |
asm volatile ( |
"mfmsr %0\n" |
"mfmsr %1\n" |
"rlwinm %1, %1, 0, 17, 15\n" |
"mtmsr %1\n" |
: "=r" (v), "=r" (tmp) |
); |
return v; |
} |
/** Restore interrupt priority level. |
* |
* Restore EE. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
ipl_t tmp; |
asm volatile ( |
"mfmsr %1\n" |
"rlwimi %0, %1, 0, 17, 15\n" |
"cmpw 0, %0, %1\n" |
"beq 0f\n" |
"mtmsr %0\n" |
"0:\n" |
: "=r" (ipl), "=r" (tmp) |
: "0" (ipl) |
: "cr0" |
); |
} |
/** Return interrupt priority level. |
* |
* Return EE. |
* |
* @return Current interrupt priority level. |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
ipl_t v; |
asm volatile ( |
"mfmsr %0\n" |
: "=r" (v) |
); |
return v; |
} |
/** Return base address of current stack. |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %0, %%sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
static inline void cpu_sleep(void) |
{ |
} |
static inline void cpu_halt(void) |
{ |
asm volatile ( |
"b 0\n" |
); |
} |
void asm_delay_loop(uint32_t t); |
extern void userspace_asm(uintptr_t uspace_uarg, uintptr_t stack, uintptr_t entry); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/faddr.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_FADDR_H_ |
#define KERN_ppc64_FADDR_H_ |
#include <arch/types.h> |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/debug.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2005 |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64debug |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_DEBUG_H_ |
#define KERN_ppc64_DEBUG_H_ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/include/barrier.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ppc64_BARRIER_H_ |
#define KERN_ppc64_BARRIER_H_ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("sync" ::: "memory") |
#define read_barrier() asm volatile ("sync" ::: "memory") |
#define write_barrier() asm volatile ("eieio" ::: "memory") |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/context.S |
---|
0,0 → 1,61 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/context_offset.h> |
.text |
.global context_save_arch |
.global context_restore_arch |
context_save_arch: |
CONTEXT_SAVE_ARCH_CORE r3 |
mflr r4 |
stw r4, OFFSET_PC(r3) |
mfcr r4 |
stw r4, OFFSET_CR(r3) |
# context_save returns 1 |
li r3, 1 |
blr |
context_restore_arch: |
CONTEXT_RESTORE_ARCH_CORE r3 |
lwz r4, OFFSET_CR(r3) |
mtcr r4 |
lwz r4, OFFSET_PC(r3) |
mtlr r4 |
# context_restore returns 0 |
li r3, 0 |
blr |
/branches/dd/kernel/arch/ppc64/src/mm/frame.c |
---|
0,0 → 1,84 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/boot/boot.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <align.h> |
#include <macros.h> |
#include <print.h> |
uintptr_t last_frame = 0; |
void physmem_print(void) |
{ |
unsigned int i; |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
for (i = 0; i < bootinfo.memmap.count; i++) { |
printf("%#10x %#10x\n", bootinfo.memmap.zones[i].start, |
bootinfo.memmap.zones[i].size); |
} |
} |
void frame_arch_init(void) |
{ |
pfn_t minconf = 2; |
count_t i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < bootinfo.memmap.count; i++) { |
start = ADDR2PFN(ALIGN_UP(bootinfo.memmap.zones[i].start, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(bootinfo.memmap.zones[i].size, FRAME_SIZE)); |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
else |
conf = minconf; |
zone_create(start, size, conf, 0); |
if (last_frame < ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE)) |
last_frame = ALIGN_UP(bootinfo.memmap.zones[i].start + bootinfo.memmap.zones[i].size, FRAME_SIZE); |
} |
/* First is exception vector, second is 'implementation specific', third and fourth is reserved */ |
frame_mark_unavailable(0, 4); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/mm/page.c |
---|
0,0 → 1,305 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <arch/types.h> |
#include <arch/exception.h> |
#include <align.h> |
#include <config.h> |
#include <print.h> |
#include <symtab.h> |
static phte_t *phte; |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
* The as->lock must be held on entry to this function |
* if lock is true. |
* |
* @param as Address space. |
* @param lock Lock/unlock the address space. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* @return PTE on success, NULL otherwise. |
* |
*/ |
static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access, |
istate_t *istate, int *pfrc) |
{ |
/* |
* Check if the mapping exists in page tables. |
*/ |
pte_t *pte = page_mapping_find(as, badvaddr); |
if ((pte) && (pte->p)) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
*/ |
return pte; |
} else { |
int rc; |
/* |
* Mapping not found in page tables. |
* Resort to higher-level page fault handler. |
*/ |
page_table_unlock(as, lock); |
switch (rc = as_page_fault(badvaddr, access, istate)) { |
case AS_PF_OK: |
/* |
* The higher-level page fault handler succeeded, |
* The mapping ought to be in place. |
*/ |
page_table_lock(as, lock); |
pte = page_mapping_find(as, badvaddr); |
ASSERT((pte) && (pte->p)); |
*pfrc = 0; |
return pte; |
case AS_PF_DEFER: |
page_table_lock(as, lock); |
*pfrc = rc; |
return NULL; |
case AS_PF_FAULT: |
page_table_lock(as, lock); |
printf("Page fault.\n"); |
*pfrc = rc; |
return NULL; |
default: |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) |
{ |
char *symbol = ""; |
char *sym2 = ""; |
char *s = get_symtab_entry(istate->pc); |
if (s) |
symbol = s; |
s = get_symtab_entry(istate->lr); |
if (s) |
sym2 = s; |
panic("%p: PHT Refill Exception at %p (%s<-%s)\n", badvaddr, istate->pc, symbol, sym2); |
} |
static void pht_insert(const uintptr_t vaddr, const pfn_t pfn) |
{ |
uint32_t page = (vaddr >> 12) & 0xffff; |
uint32_t api = (vaddr >> 22) & 0x3f; |
uint32_t vsid; |
asm volatile ( |
"mfsrin %0, %1\n" |
: "=r" (vsid) |
: "r" (vaddr) |
); |
/* Primary hash (xor) */ |
uint32_t h = 0; |
uint32_t hash = vsid ^ page; |
uint32_t base = (hash & 0x3ff) << 3; |
uint32_t i; |
bool found = false; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base + i].v) || ((phte[base + i].vsid == vsid) && (phte[base + i].api == api))) { |
found = true; |
break; |
} |
} |
if (!found) { |
/* Secondary hash (not) */ |
uint32_t base2 = (~hash & 0x3ff) << 3; |
/* Find unused or colliding |
PTE in PTEG */ |
for (i = 0; i < 8; i++) { |
if ((!phte[base2 + i].v) || ((phte[base2 + i].vsid == vsid) && (phte[base2 + i].api == api))) { |
found = true; |
base = base2; |
h = 1; |
break; |
} |
} |
if (!found) { |
// TODO: A/C precedence groups |
i = page % 8; |
} |
} |
phte[base + i].v = 1; |
phte[base + i].vsid = vsid; |
phte[base + i].h = h; |
phte[base + i].api = api; |
phte[base + i].rpn = pfn; |
phte[base + i].r = 0; |
phte[base + i].c = 0; |
phte[base + i].pp = 2; // FIXME |
} |
/** Process Instruction/Data Storage Interrupt |
* |
* @param data True if Data Storage Interrupt. |
* @param istate Interrupted register context. |
* |
*/ |
void pht_refill(bool data, istate_t *istate) |
{ |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
as_t *as; |
bool lock; |
if (AS == NULL) { |
as = AS_KERNEL; |
lock = false; |
} else { |
as = AS; |
lock = true; |
} |
if (data) { |
asm volatile ( |
"mfdar %0\n" |
: "=r" (badvaddr) |
); |
} else |
badvaddr = istate->pc; |
page_table_lock(as, lock); |
pte = find_mapping_and_check(as, lock, badvaddr, PF_ACCESS_READ /* FIXME */, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
case AS_PF_FAULT: |
goto fail; |
break; |
case AS_PF_DEFER: |
/* |
* The page fault came during copy_from_uspace() |
* or copy_to_uspace(). |
*/ |
page_table_unlock(as, lock); |
return; |
default: |
panic("Unexpected pfrc (%d)\n", pfrc); |
} |
} |
pte->a = 1; /* Record access to PTE */ |
pht_insert(badvaddr, pte->pfn); |
page_table_unlock(as, lock); |
return; |
fail: |
page_table_unlock(as, lock); |
pht_refill_fail(badvaddr, istate); |
} |
void pht_init(void) |
{ |
memsetb((uintptr_t) phte, 1 << PHT_BITS, 0); |
} |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
uintptr_t cur; |
int flags; |
for (cur = 128 << 20; cur < last_frame; cur += FRAME_SIZE) { |
flags = PAGE_CACHEABLE | PAGE_WRITE; |
if ((PA2KA(cur) >= config.base) && (PA2KA(cur) < config.base + config.kernel_size)) |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
/* Allocate page hash table */ |
phte_t *physical_phte = (phte_t *) frame_alloc(PHT_ORDER, FRAME_KA | FRAME_ATOMIC); |
ASSERT((uintptr_t) physical_phte % (1 << PHT_BITS) == 0); |
pht_init(); |
asm volatile ( |
"mtsdr1 %0\n" |
: |
: "r" ((uintptr_t) physical_phte) |
); |
} |
} |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++) |
page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_WRITE); |
last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE); |
return virtaddr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/mm/as.c |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/as.h> |
#include <genarch/mm/page_pt.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/mm/tlb.c |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64mm |
* @{ |
*/ |
/** @file |
*/ |
#include <mm/tlb.h> |
/** Initialize Page Hash Table. |
* |
* Setup the Page Hash Table with no entries. |
* |
*/ |
void tlb_arch_init(void) |
{ |
tlb_invalidate_all(); |
} |
void tlb_invalidate_all(void) |
{ |
asm volatile ( |
"tlbia\n" |
"tlbsync\n" |
); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
tlb_invalidate_all(); |
} |
/** Print contents of Page Hash Table. */ |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/ppc64.c |
---|
0,0 → 1,144 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <arch/boot/boot.h> |
#include <arch/interrupt.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <userspace.h> |
#include <proc/uarg.h> |
#include <console/console.h> |
bootinfo_t bootinfo; |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo.taskmap.count; |
uint32_t i; |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = PA2KA(bootinfo.taskmap.tasks[i].addr); |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
} |
} |
void arch_pre_mm_init(void) |
{ |
/* Initialize dispatch table */ |
interrupt_init(); |
/* Start decrementer */ |
start_decrementer(); |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* Initialize framebuffer */ |
unsigned int visual; |
switch (bootinfo.screen.bpp) { |
case 8: |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
visual = VISUAL_RGB_5_5_5; |
break; |
case 24: |
visual = VISUAL_RGB_8_8_8; |
break; |
case 32: |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel"); |
} |
fb_init(bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.scanline, visual); |
/* Merge all zones to 1 big zone */ |
zone_merge_all(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
} |
void arch_post_smp_init(void) |
{ |
} |
void calibrate_delay_loop(void) |
{ |
} |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
userspace_asm((uintptr_t) kernel_uarg->uspace_uarg, (uintptr_t) kernel_uarg->uspace_stack + THREAD_STACK_SIZE - SP_DELTA, (uintptr_t) kernel_uarg->uspace_entry); |
/* Unreachable */ |
for (;;) |
; |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/interrupt.c |
---|
0,0 → 1,108 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64interrupt |
* @{ |
*/ |
/** @file |
*/ |
#include <ddi/irq.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <time/clock.h> |
#include <ipc/sysipc.h> |
#include <arch/drivers/pic.h> |
#include <arch/mm/tlb.h> |
#include <print.h> |
void start_decrementer(void) |
{ |
asm volatile ( |
"mtdec %0\n" |
: |
: "r" (1000) |
); |
} |
/** Handler of external interrupts */ |
static void exception_external(int n, istate_t *istate) |
{ |
int inum; |
while ((inum = pic_get_pending()) != -1) { |
bool ack = false; |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Acknowledge the interrupt before processing */ |
pic_ack_interrupt(inum); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
pic_ack_interrupt(inum); |
} |
} |
static void exception_decrementer(int n, istate_t *istate) |
{ |
clock(); |
start_decrementer(); |
} |
/* Initialize basic tables for exception dispatching */ |
void interrupt_init(void) |
{ |
exc_register(VECTOR_EXTERNAL, "external", exception_external); |
exc_register(VECTOR_DECREMENTER, "timer", exception_decrementer); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/ddi/ddi.c |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64ddi |
* @{ |
*/ |
/** @file |
*/ |
#include <ddi/ddi.h> |
#include <proc/task.h> |
#include <arch/types.h> |
/** Enable I/O space range for task. |
* |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
return 0; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/cpu/cpu.c |
---|
0,0 → 1,60 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/cpu.h> |
#include <arch/cpuid.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
void cpu_arch_init(void) |
{ |
} |
void cpu_identify(void) |
{ |
cpu_info_t info; |
cpu_version(&info); |
CPU->arch.version = info.version; |
CPU->arch.revision = info.revision; |
} |
void cpu_print_report(cpu_t *m) |
{ |
printf("cpu%d: version=%d, revision=%d\n", m->id, m->arch.version, m->arch.revision); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/drivers/pic.c |
---|
0,0 → 1,94 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/drivers/pic.h> |
#include <mm/page.h> |
#include <byteorder.h> |
#include <bitops.h> |
static volatile uint32_t *pic; |
void pic_init(uintptr_t base, size_t size) |
{ |
pic = (uint32_t *) hw_map(base, size); |
} |
void pic_enable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] | (1 << intnum); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] | (1 << (intnum - 32)); |
} |
} |
void pic_disable_interrupt(int intnum) |
{ |
if (intnum < 32) { |
pic[PIC_MASK_LOW] = pic[PIC_MASK_LOW] & (~(1 << intnum)); |
} else { |
pic[PIC_MASK_HIGH] = pic[PIC_MASK_HIGH] & (~(1 << (intnum - 32))); |
} |
} |
void pic_ack_interrupt(int intnum) |
{ |
if (intnum < 32) |
pic[PIC_ACK_LOW] = 1 << intnum; |
else |
pic[PIC_ACK_HIGH] = 1 << (intnum - 32); |
} |
/** Return number of pending interrupt */ |
int pic_get_pending(void) |
{ |
int pending; |
pending = pic[PIC_PENDING_LOW]; |
if (pending) |
return fnzb32(pending); |
pending = pic[PIC_PENDING_HIGH]; |
if (pending) |
return fnzb32(pending) + 32; |
return -1; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/exception.S |
---|
0,0 → 1,237 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/mm/page.h> |
.section K_UNMAPPED_TEXT_START, "ax" |
.macro CONTEXT_STORE |
# save R12 in SPRG1, backup CR in R12 |
# save SP in SPRG2 |
mtsprg1 r12 |
mfcr r12 |
mtsprg2 sp |
# check whether SP is in kernel |
andis. sp, sp, 0x8000 |
bne 1f |
# stack is in user-space |
mfsprg0 sp |
b 2f |
1: |
# stack is in kernel |
mfsprg2 sp |
subis sp, sp, 0x8000 |
2: |
subi sp, sp, 160 |
stw r0, 8(sp) |
stw r2, 12(sp) |
stw r3, 16(sp) |
stw r4, 20(sp) |
stw r5, 24(sp) |
stw r6, 28(sp) |
stw r7, 32(sp) |
stw r8, 36(sp) |
stw r9, 40(sp) |
stw r10, 44(sp) |
stw r11, 48(sp) |
stw r13, 52(sp) |
stw r14, 56(sp) |
stw r15, 60(sp) |
stw r16, 64(sp) |
stw r17, 68(sp) |
stw r18, 72(sp) |
stw r19, 76(sp) |
stw r20, 80(sp) |
stw r21, 84(sp) |
stw r22, 88(sp) |
stw r23, 92(sp) |
stw r24, 96(sp) |
stw r25, 100(sp) |
stw r26, 104(sp) |
stw r27, 108(sp) |
stw r28, 112(sp) |
stw r29, 116(sp) |
stw r30, 120(sp) |
stw r31, 124(sp) |
stw r12, 128(sp) |
mfsrr0 r12 |
stw r12, 132(sp) |
mfsrr1 r12 |
stw r12, 136(sp) |
mflr r12 |
stw r12, 140(sp) |
mfctr r12 |
stw r12, 144(sp) |
mfxer r12 |
stw r12, 148(sp) |
mfsprg1 r12 |
stw r12, 152(sp) |
mfsprg2 r12 |
stw r12, 156(sp) |
.endm |
.org 0x060 |
jump_to_kernel: |
lis r12, iret@ha |
addi r12, r12, iret@l |
mtlr r12 |
mfmsr r12 |
ori r12, r12, (msr_ir | msr_dr)@l |
mtsrr1 r12 |
addis sp, sp, 0x8000 |
mr r4, sp |
addi r4, r4, 8 |
rfi |
jump_to_kernel_syscall: |
lis r12, syscall_handler@ha |
addi r12, r12, syscall_handler@l |
mtsrr0 r12 |
lis r12, iret_syscall@ha |
addi r12, r12, iret_syscall@l |
mtlr r12 |
mfmsr r12 |
ori r12, r12, (msr_ir | msr_dr)@l |
mtsrr1 r12 |
addis sp, sp, 0x8000 |
rfi |
.org 0x100 |
.global exc_system_reset |
exc_system_reset: |
b exc_system_reset |
.org 0x200 |
.global exc_machine_check |
exc_machine_check: |
b exc_machine_check |
.org 0x300 |
.global exc_data_storage |
exc_data_storage: |
CONTEXT_STORE |
lis r12, pht_refill@ha |
addi r12, r12, pht_refill@l |
mtsrr0 r12 |
li r3, 1 |
b jump_to_kernel |
.org 0x400 |
.global exc_instruction_storage |
exc_instruction_storage: |
CONTEXT_STORE |
lis r12, pht_refill@ha |
addi r12, r12, pht_refill@l |
mtsrr0 r12 |
li r3, 0 |
b jump_to_kernel |
.org 0x500 |
.global exc_external |
exc_external: |
b exc_external |
.org 0x600 |
.global exc_alignment |
exc_alignment: |
b exc_alignment |
.org 0x700 |
.global exc_program |
exc_program: |
b exc_program |
.org 0x800 |
.global exc_fp_unavailable |
exc_fp_unavailable: |
b exc_fp_unavailable |
.org 0x900 |
.global exc_decrementer |
exc_decrementer: |
CONTEXT_STORE |
lis r12, exc_dispatch@ha |
addi r12, r12, exc_dispatch@l |
mtsrr0 r12 |
li r3, 10 |
b jump_to_kernel |
.org 0xa00 |
.global exc_reserved0 |
exc_reserved0: |
b exc_reserved0 |
.org 0xb00 |
.global exc_reserved1 |
exc_reserved1: |
b exc_reserved1 |
.org 0xc00 |
.global exc_syscall |
exc_syscall: |
CONTEXT_STORE |
b jump_to_kernel_syscall |
.org 0xd00 |
.global exc_trace |
exc_trace: |
b exc_trace |
/branches/dd/kernel/arch/ppc64/src/fpu_context.S |
---|
0,0 → 1,105 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/context_offset.h> |
.text |
.global fpu_context_save |
.global fpu_context_restore |
.global fpu_init |
.global fpu_enable |
.global fpu_disable |
.macro FPU_CONTEXT_STORE r |
stfd fr14, OFFSET_FR14(\r) |
stfd fr15, OFFSET_FR15(\r) |
stfd fr16, OFFSET_FR16(\r) |
stfd fr17, OFFSET_FR17(\r) |
stfd fr18, OFFSET_FR18(\r) |
stfd fr19, OFFSET_FR19(\r) |
stfd fr20, OFFSET_FR20(\r) |
stfd fr21, OFFSET_FR21(\r) |
stfd fr22, OFFSET_FR22(\r) |
stfd fr23, OFFSET_FR23(\r) |
stfd fr24, OFFSET_FR24(\r) |
stfd fr25, OFFSET_FR25(\r) |
stfd fr26, OFFSET_FR26(\r) |
stfd fr27, OFFSET_FR27(\r) |
stfd fr28, OFFSET_FR28(\r) |
stfd fr29, OFFSET_FR29(\r) |
stfd fr30, OFFSET_FR30(\r) |
stfd fr31, OFFSET_FR31(\r) |
.endm |
.macro FPU_CONTEXT_LOAD r |
lfd fr14, OFFSET_FR14(\r) |
lfd fr15, OFFSET_FR15(\r) |
lfd fr16, OFFSET_FR16(\r) |
lfd fr17, OFFSET_FR17(\r) |
lfd fr18, OFFSET_FR18(\r) |
lfd fr19, OFFSET_FR19(\r) |
lfd fr20, OFFSET_FR20(\r) |
lfd fr21, OFFSET_FR21(\r) |
lfd fr22, OFFSET_FR22(\r) |
lfd fr23, OFFSET_FR23(\r) |
lfd fr24, OFFSET_FR24(\r) |
lfd fr25, OFFSET_FR25(\r) |
lfd fr26, OFFSET_FR26(\r) |
lfd fr27, OFFSET_FR27(\r) |
lfd fr28, OFFSET_FR28(\r) |
lfd fr29, OFFSET_FR29(\r) |
lfd fr30, OFFSET_FR30(\r) |
lfd fr31, OFFSET_FR31(\r) |
.endm |
fpu_context_save: |
// FPU_CONTEXT_STORE r3 |
// |
// mffs fr0 |
// stfd fr0, OFFSET_FPSCR(r3) |
blr |
fpu_context_restore: |
// FPU_CONTEXT_LOAD r3 |
// |
// lfd fr0, OFFSET_FPSCR(r3) |
// mtfsf 7, fr0 |
blr |
fpu_init: |
blr |
fpu_enable: |
blr |
fpu_disable: |
blr |
/branches/dd/kernel/arch/ppc64/src/asm.S |
---|
0,0 → 1,311 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
.text |
.global userspace_asm |
.global iret |
.global iret_syscall |
.global memsetb |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
userspace_asm: |
# r3 = uspace_uarg |
# r4 = stack |
# r5 = entry |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
# set entry point |
mtsrr0 r5 |
# set problem state, enable interrupts |
ori r31, r31, msr_pr |
ori r31, r31, msr_ee |
mtsrr1 r31 |
# set stack |
mr sp, r4 |
# jump to userspace |
rfi |
iret: |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r3, 16(sp) |
lwz r4, 20(sp) |
lwz r5, 24(sp) |
lwz r6, 28(sp) |
lwz r7, 32(sp) |
lwz r8, 36(sp) |
lwz r9, 40(sp) |
lwz r10, 44(sp) |
lwz r11, 48(sp) |
lwz r13, 52(sp) |
lwz r14, 56(sp) |
lwz r15, 60(sp) |
lwz r16, 64(sp) |
lwz r17, 68(sp) |
lwz r18, 72(sp) |
lwz r19, 76(sp) |
lwz r20, 80(sp) |
lwz r21, 84(sp) |
lwz r22, 88(sp) |
lwz r23, 92(sp) |
lwz r24, 96(sp) |
lwz r25, 100(sp) |
lwz r26, 104(sp) |
lwz r27, 108(sp) |
lwz r28, 112(sp) |
lwz r29, 116(sp) |
lwz r30, 120(sp) |
lwz r31, 124(sp) |
lwz r12, 128(sp) |
mtcr r12 |
lwz r12, 132(sp) |
mtsrr0 r12 |
lwz r12, 136(sp) |
mtsrr1 r12 |
lwz r12, 140(sp) |
mtlr r12 |
lwz r12, 144(sp) |
mtctr r12 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
iret_syscall: |
# reset decrementer |
li r31, 1000 |
mtdec r31 |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
lwz r0, 8(sp) |
lwz r2, 12(sp) |
lwz r4, 20(sp) |
lwz r5, 24(sp) |
lwz r6, 28(sp) |
lwz r7, 32(sp) |
lwz r8, 36(sp) |
lwz r9, 40(sp) |
lwz r10, 44(sp) |
lwz r11, 48(sp) |
lwz r13, 52(sp) |
lwz r14, 56(sp) |
lwz r15, 60(sp) |
lwz r16, 64(sp) |
lwz r17, 68(sp) |
lwz r18, 72(sp) |
lwz r19, 76(sp) |
lwz r20, 80(sp) |
lwz r21, 84(sp) |
lwz r22, 88(sp) |
lwz r23, 92(sp) |
lwz r24, 96(sp) |
lwz r25, 100(sp) |
lwz r26, 104(sp) |
lwz r27, 108(sp) |
lwz r28, 112(sp) |
lwz r29, 116(sp) |
lwz r30, 120(sp) |
lwz r31, 124(sp) |
lwz r12, 128(sp) |
mtcr r12 |
lwz r12, 132(sp) |
mtsrr0 r12 |
lwz r12, 136(sp) |
mtsrr1 r12 |
lwz r12, 140(sp) |
mtlr r12 |
lwz r12, 144(sp) |
mtctr r12 |
lwz r12, 148(sp) |
mtxer r12 |
lwz r12, 152(sp) |
lwz sp, 156(sp) |
rfi |
memsetb: |
rlwimi r5, r5, 8, 16, 23 |
rlwimi r5, r5, 16, 0, 15 |
addi r14, r3, -4 |
cmplwi 0, r4, 4 |
blt 7f |
stwu r5, 4(r14) |
beqlr |
andi. r15, r14, 3 |
add r4, r15, r4 |
subf r14, r15, r14 |
srwi r15, r4, 2 |
mtctr r15 |
bdz 6f |
1: |
stwu r5, 4(r14) |
bdnz 1b |
6: |
andi. r4, r4, 3 |
7: |
cmpwi 0, r4, 0 |
beqlr |
mtctr r4 |
addi r6, r6, 3 |
8: |
stbu r5, 1(r14) |
bdnz 8b |
blr |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
srwi. r7, r5, 3 |
addi r6, r3, -4 |
addi r4, r4, -4 |
beq 2f |
andi. r0, r6, 3 |
mtctr r7 |
bne 5f |
1: |
lwz r7, 4(r4) |
lwzu r8, 8(r4) |
stw r7, 4(r6) |
stwu r8, 8(r6) |
bdnz 1b |
andi. r5, r5, 7 |
2: |
cmplwi 0, r5, 4 |
blt 3f |
lwzu r0, 4(r4) |
addi r5, r5, -4 |
stwu r0, 4(r6) |
3: |
cmpwi 0, r5, 0 |
beqlr |
mtctr r5 |
addi r4, r4, 3 |
addi r6, r6, 3 |
4: |
lbzu r0, 1(r4) |
stbu r0, 1(r6) |
bdnz 4b |
blr |
5: |
subfic r0, r0, 4 |
mtctr r0 |
6: |
lbz r7, 4(r4) |
addi r4, r4, 1 |
stb r7, 4(r6) |
addi r6, r6, 1 |
bdnz 6b |
subf r5, r0, r5 |
rlwinm. r7, r5, 32-3, 3, 31 |
beq 2b |
mtctr r7 |
b 1b |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
b memcpy_from_uspace_failover_address |
/branches/dd/kernel/arch/ppc64/src/boot/boot.S |
---|
0,0 → 1,81 |
# |
# Copyright (c) 2005 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/regname.h> |
#include <arch/boot/boot.h> |
.section K_TEXT_START, "ax" |
.global kernel_image_start |
kernel_image_start: |
# load temporal kernel stack |
lis sp, kernel_stack@ha |
addi sp, sp, kernel_stack@l |
# set kernel stack for interrupt handling |
mr r31, sp |
subis r31, r31, 0x8000 |
mtsprg0 r31 |
# r3 contains physical address of bootinfo_t |
# r4 contains size of bootinfo_t |
addis r3, r3, 0x8000 |
lis r31, bootinfo@ha |
addi r31, r31, bootinfo@l # r31 = bootinfo |
cmpwi r4, 0 |
beq bootinfo_end |
bootinfo_loop: |
lwz r30, 0(r3) |
stw r30, 0(r31) |
addi r3, r3, 4 |
addi r31, r31, 4 |
subi r4, r4, 4 |
cmpwi r4, 0 |
bgt bootinfo_loop |
bootinfo_end: |
bl arch_pre_main |
b main_bsp |
.section K_DATA_START, "aw", @progbits |
.align 12 |
kernel_stack_bottom: |
.space TEMP_STACK_SIZE |
kernel_stack: |
/branches/dd/kernel/arch/ppc64/src/proc/scheduler.c |
---|
0,0 → 1,63 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ppc64proc |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <arch/boot/boot.h> |
#include <proc/scheduler.h> |
#include <proc/thread.h> |
#include <arch.h> |
/** Perform ppc64 specific tasks needed before the new task is run. */ |
void before_task_runs_arch(void) |
{ |
} |
/** Perform ppc64 specific tasks needed before the new thread is scheduled. */ |
void before_thread_runs_arch(void) |
{ |
pht_init(); |
tlb_invalidate_all(); |
asm volatile ( |
"mtsprg0 %0\n" |
: |
: "r" (KA2PA(&THREAD->kstack[THREAD_STACK_SIZE - SP_DELTA])) |
); |
} |
void after_thread_ran_arch(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ppc64/src/debug/panic.s |
---|
0,0 → 1,38 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/asm/macro.h> |
.text |
.global panic_printf |
panic_printf: |
lis %r14, halt@ha |
addi %r14, %r14, halt@l |
mtlr %r14 # fake stack to make printf return to halt |
b printf |
/branches/dd/kernel/arch/ppc64/src/dummy.s |
---|
0,0 → 1,38 |
# |
# Copyright (c) 2005 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.global asm_delay_loop |
.global sys_tls_set |
sys_tls_set: |
b sys_tls_set |
asm_delay_loop: |
blr |
/branches/dd/kernel/arch/ppc64/Makefile.inc |
---|
0,0 → 1,72 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
BFD = binary |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64 |
GCC_CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
LFLAGS += -no-check-sections -N |
DEFS += -D__64_BITS__ |
## Own configuration directives |
# |
CONFIG_FB = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/fpu_context.S \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/ppc64.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/exception.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/drivers/pic.c |
/branches/dd/kernel/arch/ppc64/_link.ld.in |
---|
0,0 → 1,58 |
/** PPC64 linker script |
* |
* umapped section: |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* |
*/ |
#include <arch/boot/boot.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
OUTPUT_FORMAT("elf64-powerpc") |
OUTPUT_ARCH(powerpc:common64) |
SECTIONS { |
.unmapped 0: AT (0) { |
unmapped_ktext_start = .; |
*(K_UNMAPPED_TEXT_START); |
unmapped_ktext_end = .; |
unmapped_kdata_start = .; |
*(K_UNMAPPED_DATA_START); |
unmapped_kdata_start = .; |
} |
.mapped PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
ktext_end = .; |
kdata_start = .; |
*(K_DATA_START); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
} |
/branches/dd/kernel/arch/sparc64/include/cpu_node.h |
---|
File deleted |
/branches/dd/kernel/arch/sparc64/include/cpu_family.h |
---|
File deleted |
/branches/dd/kernel/arch/sparc64/include/mm/cache_spec.h |
---|
File deleted |
/branches/dd/kernel/arch/sparc64/include/mm/frame.h |
---|
59,13 → 59,8 |
union frame_address { |
uintptr_t address; |
struct { |
#if defined (US) |
unsigned : 23; |
uint64_t pfn : 28; /**< Physical Frame Number. */ |
#elif defined (US3) |
unsigned : 21; |
uint64_t pfn : 30; /**< Physical Frame Number. */ |
#endif |
unsigned offset : 13; /**< Offset. */ |
} __attribute__ ((packed)); |
}; |
/branches/dd/kernel/arch/sparc64/include/mm/tlb.h |
---|
35,17 → 35,9 |
#ifndef KERN_sparc64_TLB_H_ |
#define KERN_sparc64_TLB_H_ |
#if defined (US) |
#define ITLB_ENTRY_COUNT 64 |
#define DTLB_ENTRY_COUNT 64 |
#define DTLB_MAX_LOCKED_ENTRIES DTLB_ENTRY_COUNT |
#endif |
/** TLB_DSMALL is the only of the three DMMUs that can hold locked entries. */ |
#if defined (US3) |
#define DTLB_MAX_LOCKED_ENTRIES 16 |
#endif |
#define MEM_CONTEXT_KERNEL 0 |
#define MEM_CONTEXT_TEMP 1 |
61,9 → 53,6 |
/* TLB Demap Operation types. */ |
#define TLB_DEMAP_PAGE 0 |
#define TLB_DEMAP_CONTEXT 1 |
#if defined (US3) |
#define TLB_DEMAP_ALL 2 |
#endif |
#define TLB_DEMAP_TYPE_SHIFT 6 |
72,18 → 61,6 |
#define TLB_DEMAP_SECONDARY 1 |
#define TLB_DEMAP_NUCLEUS 2 |
/* There are more TLBs in one MMU in US3, their codes are defined here. */ |
#if defined (US3) |
/* D-MMU: one small (16-entry) TLB and two big (512-entry) TLBs */ |
#define TLB_DSMALL 0 |
#define TLB_DBIG_0 2 |
#define TLB_DBIG_1 3 |
/* I-MMU: one small (16-entry) TLB and one big TLB */ |
#define TLB_ISMALL 0 |
#define TLB_IBIG 2 |
#endif |
#define TLB_DEMAP_CONTEXT_SHIFT 4 |
/* TLB Tag Access shifts */ |
99,8 → 76,6 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/cpu.h> |
union tlb_context_reg { |
uint64_t v; |
115,9 → 90,6 |
typedef tte_data_t tlb_data_t; |
/** I-/D-TLB Data Access Address in Alternate Space. */ |
#if defined (US) |
union tlb_data_access_addr { |
uint64_t value; |
struct { |
126,54 → 98,9 |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union tlb_data_access_addr dtlb_data_access_addr_t; |
typedef union tlb_data_access_addr dtlb_tag_read_addr_t; |
typedef union tlb_data_access_addr itlb_data_access_addr_t; |
typedef union tlb_data_access_addr itlb_tag_read_addr_t; |
typedef union tlb_data_access_addr tlb_data_access_addr_t; |
typedef union tlb_data_access_addr tlb_tag_read_addr_t; |
#elif defined (US3) |
/* |
* In US3, I-MMU and D-MMU have different formats of the data |
* access register virtual address. In the corresponding |
* structures the member variable for the entry number is |
* called "local_tlb_entry" - it contrasts with the "tlb_entry" |
* for the US data access register VA structure. The rationale |
* behind this is to prevent careless mistakes in the code |
* caused by setting only the entry number and not the TLB |
* number in the US3 code (when taking the code from US). |
*/ |
union dtlb_data_access_addr { |
uint64_t value; |
struct { |
uint64_t : 45; |
unsigned : 1; |
unsigned tlb_number : 2; |
unsigned : 4; |
unsigned local_tlb_entry : 9; |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union dtlb_data_access_addr dtlb_data_access_addr_t; |
typedef union dtlb_data_access_addr dtlb_tag_read_addr_t; |
union itlb_data_access_addr { |
uint64_t value; |
struct { |
uint64_t : 45; |
unsigned : 1; |
unsigned tlb_number : 2; |
unsigned : 6; |
unsigned local_tlb_entry : 7; |
unsigned : 3; |
} __attribute__ ((packed)); |
}; |
typedef union itlb_data_access_addr itlb_data_access_addr_t; |
typedef union itlb_data_access_addr itlb_tag_read_addr_t; |
#endif |
/** I-/D-TLB Tag Read Register. */ |
union tlb_tag_read_reg { |
uint64_t value; |
191,13 → 118,8 |
uint64_t value; |
struct { |
uint64_t vpn: 51; /**< Virtual Address bits 63:13. */ |
#if defined (US) |
unsigned : 6; /**< Ignored. */ |
unsigned type : 1; /**< The type of demap operation. */ |
#elif defined (US3) |
unsigned : 5; /**< Ignored. */ |
unsigned type: 2; /**< The type of demap operation. */ |
#endif |
unsigned context : 2; /**< Context register selection. */ |
unsigned : 4; /**< Zero. */ |
} __attribute__ ((packed)); |
208,19 → 130,10 |
union tlb_sfsr_reg { |
uint64_t value; |
struct { |
#if defined (US) |
unsigned long : 40; /**< Implementation dependent. */ |
unsigned asi : 8; /**< ASI. */ |
unsigned : 2; |
unsigned ft : 7; /**< Fault type. */ |
#elif defined (US3) |
unsigned long : 39; /**< Implementation dependent. */ |
unsigned nf : 1; /**< Non-faulting load. */ |
unsigned asi : 8; /**< ASI. */ |
unsigned tm : 1; /**< I-TLB miss. */ |
unsigned : 3; /**< Reserved. */ |
unsigned ft : 5; /**< Fault type. */ |
#endif |
unsigned e : 1; /**< Side-effect bit. */ |
unsigned ct : 2; /**< Context Register selection. */ |
unsigned pr : 1; /**< Privilege bit. */ |
231,53 → 144,9 |
}; |
typedef union tlb_sfsr_reg tlb_sfsr_reg_t; |
#if defined (US3) |
/* |
* Functions for determining the number of entries in TLBs. They either return |
* a constant value or a value based on the CPU autodetection. |
*/ |
/** |
* Determine the number of entries in the DMMU's small TLB. |
*/ |
static inline uint16_t tlb_dsmall_size(void) |
{ |
return 16; |
} |
/** |
* Determine the number of entries in each DMMU's big TLB. |
*/ |
static inline uint16_t tlb_dbig_size(void) |
{ |
return 512; |
} |
/** |
* Determine the number of entries in the IMMU's small TLB. |
*/ |
static inline uint16_t tlb_ismall_size(void) |
{ |
return 16; |
} |
/** |
* Determine the number of entries in the IMMU's big TLB. |
*/ |
static inline uint16_t tlb_ibig_size(void) |
{ |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIV_PLUS) |
return 512; |
else |
return 128; |
} |
#endif |
/** Read MMU Primary Context Register. |
* |
* @return Current value of Primary Context Register. |
* @return Current value of Primary Context Register. |
*/ |
static inline uint64_t mmu_primary_context_read(void) |
{ |
286,17 → 155,17 |
/** Write MMU Primary Context Register. |
* |
* @param v New value of Primary Context Register. |
* @param v New value of Primary Context Register. |
*/ |
static inline void mmu_primary_context_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_PRIMARY_CONTEXT_REG, v); |
flush_pipeline(); |
flush(); |
} |
/** Read MMU Secondary Context Register. |
* |
* @return Current value of Secondary Context Register. |
* @return Current value of Secondary Context Register. |
*/ |
static inline uint64_t mmu_secondary_context_read(void) |
{ |
305,26 → 174,23 |
/** Write MMU Primary Context Register. |
* |
* @param v New value of Primary Context Register. |
* @param v New value of Primary Context Register. |
*/ |
static inline void mmu_secondary_context_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_SECONDARY_CONTEXT_REG, v); |
flush_pipeline(); |
flush(); |
} |
#if defined (US) |
/** Read IMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
* @return Current value of specified IMMU TLB Data Access Register. |
*/ |
static inline uint64_t itlb_data_access_read(index_t entry) |
{ |
itlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
333,29 → 199,28 |
/** Write IMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param value Value to be written. |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void itlb_data_access_write(index_t entry, uint64_t value) |
{ |
itlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value); |
flush_pipeline(); |
flush(); |
} |
/** Read DMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
* @return Current value of specified DMMU TLB Data Access Register. |
*/ |
static inline uint64_t dtlb_data_access_read(index_t entry) |
{ |
dtlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
364,12 → 229,12 |
/** Write DMMU TLB Data Access Register. |
* |
* @param entry TLB Entry index. |
* @param value Value to be written. |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void dtlb_data_access_write(index_t entry, uint64_t value) |
{ |
dtlb_data_access_addr_t reg; |
tlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_entry = entry; |
379,13 → 244,13 |
/** Read IMMU TLB Tag Read Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Tag Read Register. |
* @return Current value of specified IMMU TLB Tag Read Register. |
*/ |
static inline uint64_t itlb_tag_read_read(index_t entry) |
{ |
itlb_tag_read_addr_t tag; |
tlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_entry = entry; |
394,13 → 259,13 |
/** Read DMMU TLB Tag Read Register. |
* |
* @param entry TLB Entry index. |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Tag Read Register. |
* @return Current value of specified DMMU TLB Tag Read Register. |
*/ |
static inline uint64_t dtlb_tag_read_read(index_t entry) |
{ |
dtlb_tag_read_addr_t tag; |
tlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_entry = entry; |
407,130 → 272,19 |
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); |
} |
#elif defined (US3) |
/** Read IMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t itlb_data_access_read(int tlb, index_t entry) |
{ |
itlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
return asi_u64_read(ASI_ITLB_DATA_ACCESS_REG, reg.value); |
} |
/** Write IMMU TLB Data Access Register. |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void itlb_data_access_write(int tlb, index_t entry, |
uint64_t value) |
{ |
itlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
asi_u64_write(ASI_ITLB_DATA_ACCESS_REG, reg.value, value); |
flush_pipeline(); |
} |
/** Read DMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG, TLB_DBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Data Access |
* Register. |
*/ |
static inline uint64_t dtlb_data_access_read(int tlb, index_t entry) |
{ |
dtlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
return asi_u64_read(ASI_DTLB_DATA_ACCESS_REG, reg.value); |
} |
/** Write DMMU TLB Data Access Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) |
* @param entry TLB Entry index. |
* @param value Value to be written. |
*/ |
static inline void dtlb_data_access_write(int tlb, index_t entry, |
uint64_t value) |
{ |
dtlb_data_access_addr_t reg; |
reg.value = 0; |
reg.tlb_number = tlb; |
reg.local_tlb_entry = entry; |
asi_u64_write(ASI_DTLB_DATA_ACCESS_REG, reg.value, value); |
membar(); |
} |
/** Read IMMU TLB Tag Read Register. |
* |
* @param tlb TLB number (one of TLB_ISMALL or TLB_IBIG) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified IMMU TLB Tag Read Register. |
*/ |
static inline uint64_t itlb_tag_read_read(int tlb, index_t entry) |
{ |
itlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_number = tlb; |
tag.local_tlb_entry = entry; |
return asi_u64_read(ASI_ITLB_TAG_READ_REG, tag.value); |
} |
/** Read DMMU TLB Tag Read Register. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1) |
* @param entry TLB Entry index. |
* |
* @return Current value of specified DMMU TLB Tag Read Register. |
*/ |
static inline uint64_t dtlb_tag_read_read(int tlb, index_t entry) |
{ |
dtlb_tag_read_addr_t tag; |
tag.value = 0; |
tag.tlb_number = tlb; |
tag.local_tlb_entry = entry; |
return asi_u64_read(ASI_DTLB_TAG_READ_REG, tag.value); |
} |
#endif |
/** Write IMMU TLB Tag Access Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void itlb_tag_access_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_TAG_ACCESS, v); |
flush_pipeline(); |
flush(); |
} |
/** Read IMMU TLB Tag Access Register. |
* |
* @return Current value of IMMU TLB Tag Access Register. |
* @return Current value of IMMU TLB Tag Access Register. |
*/ |
static inline uint64_t itlb_tag_access_read(void) |
{ |
539,7 → 293,7 |
/** Write DMMU TLB Tag Access Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void dtlb_tag_access_write(uint64_t v) |
{ |
549,7 → 303,7 |
/** Read DMMU TLB Tag Access Register. |
* |
* @return Current value of DMMU TLB Tag Access Register. |
* @return Current value of DMMU TLB Tag Access Register. |
*/ |
static inline uint64_t dtlb_tag_access_read(void) |
{ |
559,17 → 313,17 |
/** Write IMMU TLB Data in Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void itlb_data_in_write(uint64_t v) |
{ |
asi_u64_write(ASI_ITLB_DATA_IN_REG, 0, v); |
flush_pipeline(); |
flush(); |
} |
/** Write DMMU TLB Data in Register. |
* |
* @param v Value to be written. |
* @param v Value to be written. |
*/ |
static inline void dtlb_data_in_write(uint64_t v) |
{ |
579,7 → 333,7 |
/** Read ITLB Synchronous Fault Status Register. |
* |
* @return Current content of I-SFSR register. |
* @return Current content of I-SFSR register. |
*/ |
static inline uint64_t itlb_sfsr_read(void) |
{ |
588,17 → 342,17 |
/** Write ITLB Synchronous Fault Status Register. |
* |
* @param v New value of I-SFSR register. |
* @param v New value of I-SFSR register. |
*/ |
static inline void itlb_sfsr_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_SFSR, v); |
flush_pipeline(); |
flush(); |
} |
/** Read DTLB Synchronous Fault Status Register. |
* |
* @return Current content of D-SFSR register. |
* @return Current content of D-SFSR register. |
*/ |
static inline uint64_t dtlb_sfsr_read(void) |
{ |
607,7 → 361,7 |
/** Write DTLB Synchronous Fault Status Register. |
* |
* @param v New value of D-SFSR register. |
* @param v New value of D-SFSR register. |
*/ |
static inline void dtlb_sfsr_write(uint64_t v) |
{ |
617,7 → 371,7 |
/** Read DTLB Synchronous Fault Address Register. |
* |
* @return Current content of D-SFAR register. |
* @return Current content of D-SFAR register. |
*/ |
static inline uint64_t dtlb_sfar_read(void) |
{ |
626,11 → 380,10 |
/** Perform IMMU TLB Demap Operation. |
* |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param type Selects between context and page demap. |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
* demap. |
* @param page Address which is on the page to be demapped. |
*/ |
static inline void itlb_demap(int type, int context_encoding, uintptr_t page) |
{ |
644,19 → 397,18 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); |
flush_pipeline(); |
asi_u64_write(ASI_IMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
flush(); |
} |
/** Perform DMMU TLB Demap Operation. |
* |
* @param type Selects between context and page demap (and entire MMU |
* demap on US3). |
* @param type Selects between context and page demap. |
* @param context_encoding Specifies which Context register has Context ID for |
* demap. |
* @param page Address which is on the page to be demapped. |
* demap. |
* @param page Address which is on the page to be demapped. |
*/ |
static inline void dtlb_demap(int type, int context_encoding, uintptr_t page) |
{ |
670,17 → 422,17 |
da.context = context_encoding; |
da.vpn = pg.vpn; |
/* da.value is the address within the ASI */ |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); |
asi_u64_write(ASI_DMMU_DEMAP, da.value, 0); /* da.value is the |
* address within the |
* ASI */ |
membar(); |
} |
extern void fast_instruction_access_mmu_miss(unative_t, istate_t *); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t, istate_t *); |
extern void fast_data_access_protection(tlb_tag_access_reg_t , istate_t *); |
extern void fast_instruction_access_mmu_miss(unative_t unused, istate_t *istate); |
extern void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate); |
extern void fast_data_access_protection(tlb_tag_access_reg_t tag , istate_t *istate); |
extern void dtlb_insert_mapping(uintptr_t, uintptr_t, int, bool, bool); |
extern void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, bool locked, bool cacheable); |
extern void dump_sfsr_and_sfar(void); |
/branches/dd/kernel/arch/sparc64/include/mm/page.h |
---|
53,6 → 53,11 |
#define MMU_PAGES_PER_PAGE (1 << (PAGE_WIDTH - MMU_PAGE_WIDTH)) |
/* |
* With 16K pages, there is only one page color. |
*/ |
#define PAGE_COLOR_BITS 0 /**< 14 - 14; 2^14 == 16K == alias boundary. */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dd/kernel/arch/sparc64/include/mm/cache.h |
---|
38,6 → 38,15 |
#include <mm/page.h> |
#include <mm/frame.h> |
#define dcache_flush_page(p) \ |
dcache_flush_color(PAGE_COLOR((p))) |
#define dcache_flush_frame(p, f) \ |
dcache_flush_tag(PAGE_COLOR((p)), ADDR2PFN((f))); |
extern void dcache_flush(void); |
extern void dcache_flush_color(int c); |
extern void dcache_flush_tag(int c, pfn_t tag); |
#endif |
/** @} |
/branches/dd/kernel/arch/sparc64/include/mm/tsb.h |
---|
107,55 → 107,6 |
asi_u64_write(ASI_DMMU, VA_DMMU_TSB_BASE, v); |
} |
#if defined (US3) |
/** Write DTSB Primary Extension register. |
* |
* @param v New content of the DTSB Primary Extension register. |
*/ |
static inline void dtsb_primary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_PRIMARY_EXTENSION, v); |
} |
/** Write DTSB Secondary Extension register. |
* |
* @param v New content of the DTSB Secondary Extension register. |
*/ |
static inline void dtsb_secondary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_SECONDARY_EXTENSION, v); |
} |
/** Write DTSB Nucleus Extension register. |
* |
* @param v New content of the DTSB Nucleus Extension register. |
*/ |
static inline void dtsb_nucleus_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_DMMU, VA_DMMU_NUCLEUS_EXTENSION, v); |
} |
/** Write ITSB Primary Extension register. |
* |
* @param v New content of the ITSB Primary Extension register. |
*/ |
static inline void itsb_primary_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_PRIMARY_EXTENSION, v); |
} |
/** Write ITSB Nucleus Extension register. |
* |
* @param v New content of the ITSB Nucleus Extension register. |
*/ |
static inline void itsb_nucleus_extension_write(uint64_t v) |
{ |
asi_u64_write(ASI_IMMU, VA_IMMU_NUCLEUS_EXTENSION, v); |
} |
#endif |
/* Forward declarations. */ |
struct as; |
struct pte; |
/branches/dd/kernel/arch/sparc64/include/mm/mmu.h |
---|
35,10 → 35,8 |
#ifndef KERN_sparc64_MMU_H_ |
#define KERN_sparc64_MMU_H_ |
#if defined(US) |
/* LSU Control Register ASI. */ |
#define ASI_LSU_CONTROL_REG 0x45 /**< Load/Store Unit Control Register. */ |
#endif |
/* I-MMU ASIs. */ |
#define ASI_IMMU 0x50 |
54,12 → 52,7 |
#define VA_IMMU_SFSR 0x18 /**< IMMU sync fault status register. */ |
#define VA_IMMU_TSB_BASE 0x28 /**< IMMU TSB base register. */ |
#define VA_IMMU_TAG_ACCESS 0x30 /**< IMMU TLB tag access register. */ |
#if defined (US3) |
#define VA_IMMU_PRIMARY_EXTENSION 0x48 /**< IMMU TSB primary extension register */ |
#define VA_IMMU_NUCLEUS_EXTENSION 0x58 /**< IMMU TSB nucleus extension register */ |
#endif |
/* D-MMU ASIs. */ |
#define ASI_DMMU 0x58 |
#define ASI_DMMU_TSB_8KB_PTR_REG 0x59 |
80,11 → 73,6 |
#define VA_DMMU_TAG_ACCESS 0x30 /**< DMMU TLB tag access register. */ |
#define VA_DMMU_VA_WATCHPOINT_REG 0x38 /**< DMMU VA data watchpoint register. */ |
#define VA_DMMU_PA_WATCHPOINT_REG 0x40 /**< DMMU PA data watchpoint register. */ |
#if defined (US3) |
#define VA_DMMU_PRIMARY_EXTENSION 0x48 /**< DMMU TSB primary extension register */ |
#define VA_DMMU_SECONDARY_EXTENSION 0x50 /**< DMMU TSB secondary extension register */ |
#define VA_DMMU_NUCLEUS_EXTENSION 0x58 /**< DMMU TSB nucleus extension register */ |
#endif |
#ifndef __ASM__ |
92,7 → 80,6 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#if defined(US) |
/** LSU Control Register. */ |
typedef union { |
uint64_t value; |
113,7 → 100,6 |
} __attribute__ ((packed)); |
} lsu_cr_reg_t; |
#endif /* US */ |
#endif /* !def __ASM__ */ |
/branches/dd/kernel/arch/sparc64/include/mm/tte.h |
---|
50,7 → 50,6 |
#include <arch/types.h> |
/* TTE tag's VA_tag field contains bits <63:VA_TAG_PAGE_SHIFT> of the VA */ |
#define VA_TAG_PAGE_SHIFT 22 |
/** Translation Table Entry - Tag. */ |
76,13 → 75,8 |
unsigned nfo : 1; /**< No-Fault-Only. */ |
unsigned ie : 1; /**< Invert Endianness. */ |
unsigned soft2 : 9; /**< Software defined field. */ |
#if defined (US) |
unsigned diag : 9; /**< Diagnostic data. */ |
unsigned pfn : 28; /**< Physical Address bits, bits 40:13. */ |
#elif defined (US3) |
unsigned : 7; /**< Reserved. */ |
unsigned pfn : 30; /**< Physical Address bits, bits 42:13 */ |
#endif |
unsigned soft : 6; /**< Software defined field. */ |
unsigned l : 1; /**< Lock. */ |
unsigned cp : 1; /**< Cacheable in physically indexed cache. */ |
/branches/dd/kernel/arch/sparc64/include/trap/syscall.h |
---|
31,14 → 31,26 |
*/ |
/** |
* @file |
* @brief |
* @brief This file contains the trap_instruction handler. |
* |
* The trap_instruction trap is used to implement syscalls. |
*/ |
#ifndef KERN_sparc64_SYSCALL_TRAP_H_ |
#define KERN_sparc64_SYSCALL_TRAP_H_ |
#define TT_TRAP_INSTRUCTION_0 0x100 |
#define TT_TRAP_INSTRUCTION(n) (0x100 + (n)) |
#define TT_TRAP_INSTRUCTION_LAST TT_TRAP_INSTRUCTION(127) |
#ifdef __ASM__ |
.macro TRAP_INSTRUCTION n |
ba trap_instruction_handler |
mov TT_TRAP_INSTRUCTION(\n) - TT_TRAP_INSTRUCTION(0), %g2 |
.endm |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dd/kernel/arch/sparc64/include/trap/interrupt.h |
---|
49,43 → 49,21 |
/* Interrupt ASI registers. */ |
#define ASI_INTR_W 0x77 |
#define ASI_UDB_INTR_W 0x77 |
#define ASI_INTR_DISPATCH_STATUS 0x48 |
#define ASI_INTR_R 0x7f |
#define ASI_UDB_INTR_R 0x7f |
#define ASI_INTR_RECEIVE 0x49 |
/* VA's used with ASI_INTR_W register. */ |
#if defined (US) |
/* VA's used with ASI_UDB_INTR_W register. */ |
#define ASI_UDB_INTR_W_DATA_0 0x40 |
#define ASI_UDB_INTR_W_DATA_1 0x50 |
#define ASI_UDB_INTR_W_DATA_2 0x60 |
#elif defined (US3) |
#define VA_INTR_W_DATA_0 0x40 |
#define VA_INTR_W_DATA_1 0x48 |
#define VA_INTR_W_DATA_2 0x50 |
#define VA_INTR_W_DATA_3 0x58 |
#define VA_INTR_W_DATA_4 0x60 |
#define VA_INTR_W_DATA_5 0x68 |
#define VA_INTR_W_DATA_6 0x80 |
#define VA_INTR_W_DATA_7 0x88 |
#endif |
#define VA_INTR_W_DISPATCH 0x70 |
#define ASI_UDB_INTR_W_DISPATCH 0x70 |
/* VA's used with ASI_INTR_R register. */ |
#if defined(US) |
/* VA's used with ASI_UDB_INTR_R register. */ |
#define ASI_UDB_INTR_R_DATA_0 0x40 |
#define ASI_UDB_INTR_R_DATA_1 0x50 |
#define ASI_UDB_INTR_R_DATA_2 0x60 |
#elif defined (US3) |
#define VA_INTR_R_DATA_0 0x40 |
#define VA_INTR_R_DATA_1 0x48 |
#define VA_INTR_R_DATA_2 0x50 |
#define VA_INTR_R_DATA_3 0x58 |
#define VA_INTR_R_DATA_4 0x60 |
#define VA_INTR_R_DATA_5 0x68 |
#define VA_INTR_R_DATA_6 0x80 |
#define VA_INTR_R_DATA_7 0x88 |
#endif |
/* Shifts in the Interrupt Vector Dispatch virtual address. */ |
#define INTR_VEC_DISPATCH_MID_SHIFT 14 |
/branches/dd/kernel/arch/sparc64/include/trap/regwin.h |
---|
39,7 → 39,6 |
#include <arch/stack.h> |
#include <arch/arch.h> |
#include <align.h> |
#define TT_CLEAN_WINDOW 0x24 |
#define TT_SPILL_0_NORMAL 0x80 /* kernel spills */ |
73,11 → 72,6 |
#define I6_OFFSET 112 |
#define I7_OFFSET 120 |
/* Uspace Window Buffer constants. */ |
#define UWB_SIZE ((NWINDOWS - 1) * STACK_WINDOW_SAVE_AREA_SIZE) |
#define UWB_ALIGNMENT 1024 |
#define UWB_ASIZE ALIGN_UP(UWB_SIZE, UWB_ALIGNMENT) |
#ifdef __ASM__ |
/* |
/branches/dd/kernel/arch/sparc64/include/drivers/sgcn.h |
---|
File deleted |
/branches/dd/kernel/arch/sparc64/include/drivers/scr.h |
---|
42,14 → 42,12 |
SCR_UNKNOWN, |
SCR_ATYFB, |
SCR_FFB, |
SCR_CGSIX, |
SCR_XVR |
SCR_CGSIX |
} scr_type_t; |
extern scr_type_t scr_type; |
extern void scr_init(ofw_tree_node_t *node); |
extern void scr_redraw(void); |
#endif |
/branches/dd/kernel/arch/sparc64/include/drivers/z8530.h |
---|
0,0 → 1,140 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_Z8530_H_ |
#define KERN_sparc64_Z8530_H_ |
#include <arch/types.h> |
#include <arch/drivers/kbd.h> |
#define Z8530_CHAN_A 4 |
#define Z8530_CHAN_B 0 |
#define WR0 0 |
#define WR1 1 |
#define WR2 2 |
#define WR3 3 |
#define WR4 4 |
#define WR5 5 |
#define WR6 6 |
#define WR7 7 |
#define WR8 8 |
#define WR9 9 |
#define WR10 10 |
#define WR11 11 |
#define WR12 12 |
#define WR13 13 |
#define WR14 14 |
#define WR15 15 |
#define RR0 0 |
#define RR1 1 |
#define RR2 2 |
#define RR3 3 |
#define RR8 8 |
#define RR10 10 |
#define RR12 12 |
#define RR13 13 |
#define RR14 14 |
#define RR15 15 |
/* Write Register 0 */ |
#define WR0_TX_IP_RST (0x5<<3) /** Reset pending TX interrupt. */ |
#define WR0_ERR_RST (0x6<<3) |
/* Write Register 1 */ |
#define WR1_RID (0x0<<3) /** Receive Interrupts Disabled. */ |
#define WR1_RIFCSC (0x1<<3) /** Receive Interrupt on First Character or Special Condition. */ |
#define WR1_IARCSC (0x2<<3) /** Interrupt on All Receive Characters or Special Conditions. */ |
#define WR1_RISC (0x3<<3) /** Receive Interrupt on Special Condition. */ |
#define WR1_PISC (0x1<<2) /** Parity Is Special Condition. */ |
/* Write Register 3 */ |
#define WR3_RX_ENABLE (0x1<<0) /** Rx Enable. */ |
#define WR3_RX8BITSCH (0x3<<6) /** 8-bits per character. */ |
/* Write Register 9 */ |
#define WR9_MIE (0x1<<3) /** Master Interrupt Enable. */ |
/* Read Register 0 */ |
#define RR0_RCA (0x1<<0) /** Receive Character Available. */ |
/** Structure representing the z8530 device. */ |
typedef struct { |
devno_t devno; |
volatile uint8_t *reg; /** Memory mapped registers of the z8530. */ |
} z8530_t; |
static inline void z8530_write(z8530_t *dev, index_t chan, uint8_t reg, uint8_t val) |
{ |
/* |
* Registers 8-15 will automatically issue the Point High |
* command as their bit 3 is 1. |
*/ |
dev->reg[WR0+chan] = reg; /* select register */ |
dev->reg[WR0+chan] = val; /* write value */ |
} |
static inline void z8530_write_a(z8530_t *dev, uint8_t reg, uint8_t val) |
{ |
z8530_write(dev, Z8530_CHAN_A, reg, val); |
} |
static inline void z8530_write_b(z8530_t *dev, uint8_t reg, uint8_t val) |
{ |
z8530_write(dev, Z8530_CHAN_B, reg, val); |
} |
static inline uint8_t z8530_read(z8530_t *dev, index_t chan, uint8_t reg) |
{ |
/* |
* Registers 8-15 will automatically issue the Point High |
* command as their bit 3 is 1. |
*/ |
dev->reg[WR0+chan] = reg; /* select register */ |
return dev->reg[WR0+chan]; |
} |
static inline uint8_t z8530_read_a(z8530_t *dev, uint8_t reg) |
{ |
return z8530_read(dev, Z8530_CHAN_A, reg); |
} |
static inline uint8_t z8530_read_b(z8530_t *dev, uint8_t reg) |
{ |
return z8530_read(dev, Z8530_CHAN_B, reg); |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/include/drivers/pci.h |
---|
51,8 → 51,8 |
}; |
struct pci_operations { |
void (* enable_interrupt)(pci_t *, int); |
void (* clear_interrupt)(pci_t *, int); |
void (* enable_interrupt)(pci_t *pci, int inr); |
void (* clear_interrupt)(pci_t *pci, int inr); |
}; |
struct pci { |
61,9 → 61,9 |
volatile uint64_t *reg; /**< Registers including interrupt registers. */ |
}; |
extern pci_t *pci_init(ofw_tree_node_t *); |
extern void pci_enable_interrupt(pci_t *, int); |
extern void pci_clear_interrupt(void *, int); |
extern pci_t *pci_init(ofw_tree_node_t *node); |
extern void pci_enable_interrupt(pci_t *pci, int inr); |
extern void pci_clear_interrupt(pci_t *pci, int inr); |
#endif |
/branches/dd/kernel/arch/sparc64/include/drivers/fhc.h |
---|
44,9 → 44,9 |
extern fhc_t *central_fhc; |
extern fhc_t *fhc_init(ofw_tree_node_t *); |
extern void fhc_enable_interrupt(fhc_t *, int); |
extern void fhc_clear_interrupt(void *, int); |
extern fhc_t *fhc_init(ofw_tree_node_t *node); |
extern void fhc_enable_interrupt(fhc_t *fhc, int inr); |
extern void fhc_clear_interrupt(fhc_t *fhc, int inr); |
#endif |
/branches/dd/kernel/arch/sparc64/include/drivers/kbd.h |
---|
41,8 → 41,7 |
typedef enum { |
KBD_UNKNOWN, |
KBD_Z8530, |
KBD_NS16550, |
KBD_SGCN |
KBD_NS16550 |
} kbd_type_t; |
extern kbd_type_t kbd_type; |
/branches/dd/kernel/arch/sparc64/include/drivers/ns16550.h |
---|
0,0 → 1,102 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_sparc64_NS16550_H_ |
#define KERN_sparc64_NS16550_H_ |
#include <arch/types.h> |
#include <arch/drivers/kbd.h> |
/* NS16550 registers */ |
#define RBR_REG 0 /** Receiver Buffer Register. */ |
#define IER_REG 1 /** Interrupt Enable Register. */ |
#define IIR_REG 2 /** Interrupt Ident Register (read). */ |
#define FCR_REG 2 /** FIFO control register (write). */ |
#define LCR_REG 3 /** Line Control register. */ |
#define LSR_REG 5 /** Line Status Register. */ |
#define IER_ERBFI 0x01 /** Enable Receive Buffer Full Interrupt. */ |
#define LCR_DLAB 0x80 /** Divisor Latch Access bit. */ |
/** Structure representing the ns16550 device. */ |
typedef struct { |
devno_t devno; |
volatile uint8_t *reg; /** Memory mapped registers of the ns16550. */ |
} ns16550_t; |
static inline uint8_t ns16550_rbr_read(ns16550_t *dev) |
{ |
return dev->reg[RBR_REG]; |
} |
static inline uint8_t ns16550_ier_read(ns16550_t *dev) |
{ |
return dev->reg[IER_REG]; |
} |
static inline void ns16550_ier_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[IER_REG] = v; |
} |
static inline uint8_t ns16550_iir_read(ns16550_t *dev) |
{ |
return dev->reg[IIR_REG]; |
} |
static inline void ns16550_fcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[FCR_REG] = v; |
} |
static inline uint8_t ns16550_lcr_read(ns16550_t *dev) |
{ |
return dev->reg[LCR_REG]; |
} |
static inline void ns16550_lcr_write(ns16550_t *dev, uint8_t v) |
{ |
dev->reg[LCR_REG] = v; |
} |
static inline uint8_t ns16550_lsr_read(ns16550_t *dev) |
{ |
return dev->reg[LSR_REG]; |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/include/barrier.h |
---|
57,11 → 57,8 |
#define write_barrier() \ |
asm volatile ("membar #StoreStore\n" ::: "memory") |
#define flush(a) \ |
asm volatile ("flush %0\n" :: "r" ((a)) : "memory") |
/** Flush Instruction pipeline. */ |
static inline void flush_pipeline(void) |
/** Flush Instruction Memory instruction. */ |
static inline void flush(void) |
{ |
/* |
* The FLUSH instruction takes address parameter. |
82,39 → 79,6 |
asm volatile ("membar #Sync\n"); |
} |
#if defined (US) |
#define smc_coherence(a) \ |
{ \ |
write_barrier(); \ |
flush((a)); \ |
} |
#define FLUSH_INVAL_MIN 4 |
#define smc_coherence_block(a, l) \ |
{ \ |
unsigned long i; \ |
write_barrier(); \ |
for (i = 0; i < (l); i += FLUSH_INVAL_MIN) \ |
flush((void *)(a) + i); \ |
} |
#elif defined (US3) |
#define smc_coherence(a) \ |
{ \ |
write_barrier(); \ |
flush_pipeline(); \ |
} |
#define smc_coherence_block(a, l) \ |
{ \ |
write_barrier(); \ |
flush_pipeline(); \ |
} |
#endif /* defined(US3) */ |
#endif |
/** @} |
/branches/dd/kernel/arch/sparc64/include/types.h |
---|
35,6 → 35,10 |
#ifndef KERN_sparc64_TYPES_H_ |
#define KERN_sparc64_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
57,34 → 61,13 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
#define PRIc "llu" |
#define PRIi "llu" |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
#define PRId16 "d" |
#define PRId32 "d" |
#define PRId64 "lld" |
#define PRIdn "lld" |
#define PRIu8 "u" |
#define PRIu16 "u" |
#define PRIu32 "u" |
#define PRIu64 "llu" |
#define PRIun "llu" |
#define PRIx8 "x" |
#define PRIx16 "x" |
#define PRIx32 "x" |
#define PRIx64 "llx" |
#define PRIxn "llx" |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
typedef uint8_t asi_t; |
#endif |
/branches/dd/kernel/arch/sparc64/include/cpu.h |
---|
35,6 → 35,14 |
#ifndef KERN_sparc64_CPU_H_ |
#define KERN_sparc64_CPU_H_ |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
#define MANUF_FUJITSU 0x04 |
#define MANUF_ULTRASPARC 0x17 /**< UltraSPARC I, UltraSPARC II */ |
#define MANUF_SUN 0x3e |
43,29 → 51,14 |
#define IMPL_ULTRASPARCII 0x11 |
#define IMPL_ULTRASPARCII_I 0x12 |
#define IMPL_ULTRASPARCII_E 0x13 |
#define IMPL_ULTRASPARCIII 0x14 |
#define IMPL_ULTRASPARCIII_PLUS 0x15 |
#define IMPL_ULTRASPARCIII_I 0x16 |
#define IMPL_ULTRASPARCIV 0x18 |
#define IMPL_ULTRASPARCIII 0x15 |
#define IMPL_ULTRASPARCIV_PLUS 0x19 |
#define IMPL_SPARC64V 0x5 |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/register.h> |
#include <arch/regdef.h> |
#include <arch/asm.h> |
#ifdef CONFIG_SMP |
#include <arch/mm/cache.h> |
#endif |
typedef struct { |
uint32_t mid; /**< Processor ID as read from |
UPA_CONFIG/FIREPLANE_CONFIG. */ |
UPA_CONFIG. */ |
ver_reg_t ver; |
uint32_t clock_frequency; /**< Processor frequency in Hz. */ |
uint64_t next_tick_cmpr; /**< Next clock interrupt should be |
72,28 → 65,8 |
generated when the TICK register |
matches this value. */ |
} cpu_arch_t; |
/** |
* Reads the module ID (agent ID/CPUID) of the current CPU. |
*/ |
static inline uint32_t read_mid(void) |
{ |
uint64_t icbus_config = asi_u64_read(ASI_ICBUS_CONFIG, 0); |
icbus_config = icbus_config >> ICBUS_CONFIG_MID_SHIFT; |
#if defined (US) |
return icbus_config & 0x1f; |
#elif defined (US3) |
if (((ver_reg_t) ver_read()).impl == IMPL_ULTRASPARCIII_I) |
return icbus_config & 0x1f; |
else |
return icbus_config & 0x3ff; |
#endif |
} |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/include/atomic.h |
---|
37,7 → 37,6 |
#include <arch/barrier.h> |
#include <arch/types.h> |
#include <preemption.h> |
/** Atomic add operation. |
* |
57,8 → 56,7 |
a = *((uint64_t *) x); |
b = a + i; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), |
"+r" (b) : "r" (a)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *)x)), "+r" (b) : "r" (a)); |
} while (a != b); |
return a; |
99,8 → 97,7 |
uint64_t v = 1; |
volatile uintptr_t x = (uint64_t) &val->count; |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), |
"+r" (v) : "r" (0)); |
asm volatile ("casx %0, %2, %1\n" : "+m" (*((uint64_t *) x)), "+r" (v) : "r" (0)); |
return v; |
} |
112,8 → 109,6 |
volatile uintptr_t x = (uint64_t) &val->count; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"casx %0, %3, %1\n" |
/branches/dd/kernel/arch/sparc64/include/boot/boot.h |
---|
48,12 → 48,9 |
#define TASKMAP_MAX_RECORDS 32 |
#define MEMMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void * addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
/branches/dd/kernel/arch/sparc64/include/asm.h |
---|
37,61 → 37,11 |
#include <arch/arch.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <align.h> |
#include <arch/register.h> |
#include <config.h> |
#include <arch/stack.h> |
#include <arch/barrier.h> |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
memory_barrier(); |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uint8_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t rv; |
rv = *port; |
memory_barrier(); |
return rv; |
} |
/** Read Processor State register. |
* |
* @return Value of PSTATE register. |
136,28 → 86,6 |
asm volatile ("wr %0, %1, %%tick_cmpr\n" : : "r" (v), "i" (0)); |
} |
/** Read STICK_compare Register. |
* |
* @return Value of STICK_compare register. |
*/ |
static inline uint64_t stick_compare_read(void) |
{ |
uint64_t v; |
asm volatile ("rd %%asr25, %0\n" : "=r" (v)); |
return v; |
} |
/** Write STICK_compare Register. |
* |
* @param v New value of STICK_comapre register. |
*/ |
static inline void stick_compare_write(uint64_t v) |
{ |
asm volatile ("wr %0, %1, %%asr25\n" : : "r" (v), "i" (0)); |
} |
/** Read TICK Register. |
* |
* @return Value of TICK register. |
429,6 → 357,15 |
asm volatile ("wrpr %g0, %g0, %tl\n"); |
} |
/** Read UPA_CONFIG register. |
* |
* @return Value of the UPA_CONFIG register. |
*/ |
static inline uint64_t upa_config_read(void) |
{ |
return asi_u64_read(ASI_UPA_CONFIG, 0); |
} |
extern void cpu_halt(void); |
extern void cpu_sleep(void); |
extern void asm_delay_loop(const uint32_t usec); |
/branches/dd/kernel/arch/sparc64/include/fpu_context.h |
---|
37,6 → 37,7 |
#include <arch/types.h> |
#define ARCH_HAS_FPU |
#define FPU_CONTEXT_ALIGN 8 |
typedef struct { |
/branches/dd/kernel/arch/sparc64/include/regdef.h |
---|
55,11 → 55,8 |
#define WSTATE_NORMAL(n) (n) |
#define WSTATE_OTHER(n) ((n) << 3) |
/* |
* The following definitions concern the UPA_CONFIG register on US and the |
* FIREPLANE_CONFIG register on US3. |
*/ |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_MASK 0x1f |
#endif |
/branches/dd/kernel/arch/sparc64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/branches/dd/kernel/arch/sparc64/include/arch.h |
---|
41,16 → 41,10 |
#define ASI_AIUS 0x11 /** Access to secondary context with user privileges. */ |
#define ASI_NUCLEUS_QUAD_LDD 0x24 /** ASI for 16-byte atomic loads. */ |
#define ASI_DCACHE_TAG 0x47 /** ASI D-Cache Tag. */ |
#define ASI_ICBUS_CONFIG 0x4a /** ASI of the UPA_CONFIG/FIREPLANE_CONFIG register. */ |
#define ASI_UPA_CONFIG 0x4a /** ASI of the UPA_CONFIG register. */ |
#define NWINDOWS 8 /** Number of register window sets. */ |
#ifndef __ASM__ |
extern void arch_pre_main(void); |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dd/kernel/arch/sparc64/include/register.h |
---|
117,6 → 117,23 |
}; |
typedef union fprs_reg fprs_reg_t; |
/** UPA_CONFIG register. |
* |
* Note that format of this register differs significantly from |
* processor version to version. The format defined here |
* is the common subset for all supported processor versions. |
*/ |
union upa_config { |
uint64_t value; |
struct { |
uint64_t : 34; |
unsigned pcon : 8; /**< Processor configuration. */ |
unsigned mid : 5; /**< Module (processor) ID register. */ |
unsigned pcap : 17; /**< Processor capabilities. */ |
} __attribute__ ((packed)); |
}; |
typedef union upa_config upa_config_t; |
#endif |
/** @} |
/branches/dd/kernel/arch/sparc64/src/smp/ipi.c |
---|
46,33 → 46,6 |
#include <time/delay.h> |
#include <panic.h> |
/** Set the contents of the outgoing interrupt vector data. |
* |
* The first data item (data 0) will be set to the value of func, the |
* rest of the vector will contain zeros. |
* |
* This is a helper function used from within the cross_call function. |
* |
* @param func value the first data item of the vector will be set to |
*/ |
static inline void set_intr_w_data(void (* func)(void)) |
{ |
#if defined (US) |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_0, (uintptr_t) func); |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); |
#elif defined (US3) |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_0, (uintptr_t) func); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_2, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_3, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_4, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_5, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_6, 0); |
asi_u64_write(ASI_INTR_W, VA_INTR_W_DATA_7, 0); |
#endif |
} |
/** Invoke function on another processor. |
* |
* Currently, only functions without arguments are supported. |
98,15 → 71,16 |
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); |
if (status & INTR_DISPATCH_STATUS_BUSY) |
panic("Interrupt Dispatch Status busy bit set."); |
panic("Interrupt Dispatch Status busy bit set\n"); |
ASSERT(!(pstate_read() & PSTATE_IE_BIT)); |
do { |
set_intr_w_data(func); |
asi_u64_write(ASI_INTR_W, |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_0, |
(uintptr_t) func); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_1, 0); |
asi_u64_write(ASI_UDB_INTR_W, ASI_UDB_INTR_W_DATA_2, 0); |
asi_u64_write(ASI_UDB_INTR_W, |
(mid << INTR_VEC_DISPATCH_MID_SHIFT) | |
VA_INTR_W_DISPATCH, 0); |
ASI_UDB_INTR_W_DISPATCH, 0); |
membar(); |
151,7 → 125,7 |
func = tlb_shootdown_ipi_recv; |
break; |
default: |
panic("Unknown IPI (%d).", ipi); |
panic("Unknown IPI (%d).\n", ipi); |
break; |
} |
/branches/dd/kernel/arch/sparc64/src/smp/smp.c |
---|
35,7 → 35,6 |
#include <smp/smp.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <cpu.h> |
#include <arch/cpu_family.h> |
#include <arch/cpu.h> |
#include <arch.h> |
#include <config.h> |
44,7 → 43,6 |
#include <synch/synch.h> |
#include <synch/waitq.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* This global variable is used to pick-up application processors |
63,55 → 61,15 |
ofw_tree_node_t *node; |
count_t cnt = 0; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
cnt += 2; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
while (node) { |
cnt++; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
config.cpu_count = max(1, cnt); |
} |
/** |
* Wakes up the CPU which is represented by the "node" OFW tree node. |
* If "node" represents the current CPU, calling the function has |
* no effect. |
*/ |
static void wakeup_cpu(ofw_tree_node_t *node) |
{ |
uint32_t mid; |
ofw_tree_property_t *prop; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (!prop || prop->value == NULL) |
return; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) |
return; |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == |
ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %" PRIu32 |
") timed out\n", __func__, mid); |
} |
/** Wake application processors up. */ |
void kmp(void *arg) |
{ |
118,18 → 76,31 |
ofw_tree_node_t *node; |
int i; |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
for (i = 0; node; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) |
wakeup_cpu(node); |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
wakeup_cpu(ofw_tree_find_child(node, "cpu@0")); |
wakeup_cpu(ofw_tree_find_child(node, "cpu@1")); |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
for (i = 0; node; node = ofw_tree_find_peer_by_device_type(node, "cpu"), i++) { |
uint32_t mid; |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
if (!prop || !prop->value) |
continue; |
mid = *((uint32_t *) prop->value); |
if (CPU->arch.mid == mid) { |
/* |
* Skip the current CPU. |
*/ |
continue; |
} |
/* |
* Processor with ID == mid can proceed with its initialization. |
*/ |
waking_up_mid = mid; |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for processor (mid = %d) timed out\n", |
__func__, mid); |
} |
} |
/branches/dd/kernel/arch/sparc64/src/mm/tlb.c |
---|
54,13 → 54,14 |
#include <arch/mm/tsb.h> |
#endif |
static void dtlb_pte_copy(pte_t *, index_t, bool); |
static void itlb_pte_copy(pte_t *, index_t); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *, const char *); |
static void do_fast_data_access_mmu_miss_fault(istate_t *, tlb_tag_access_reg_t, |
const char *); |
static void do_fast_data_access_protection_fault(istate_t *, |
tlb_tag_access_reg_t, const char *); |
static void dtlb_pte_copy(pte_t *t, index_t index, bool ro); |
static void itlb_pte_copy(pte_t *t, index_t index); |
static void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str); |
static void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str); |
static void do_fast_data_access_protection_fault(istate_t *istate, |
tlb_tag_access_reg_t tag, const char *str); |
char *context_encoding[] = { |
"Primary", |
85,11 → 86,11 |
/** Insert privileged mapping into DMMU TLB. |
* |
* @param page Virtual page address. |
* @param frame Physical frame address. |
* @param pagesize Page size. |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
* @param page Virtual page address. |
* @param frame Physical frame address. |
* @param pagesize Page size. |
* @param locked True for permanent mappings, false otherwise. |
* @param cacheable True if the mapping is cacheable, false otherwise. |
*/ |
void dtlb_insert_mapping(uintptr_t page, uintptr_t frame, int pagesize, |
bool locked, bool cacheable) |
102,7 → 103,7 |
pg.address = page; |
fr.address = frame; |
tag.context = ASID_KERNEL; |
tag.value = ASID_KERNEL; |
tag.vpn = pg.vpn; |
dtlb_tag_access_write(tag.value); |
125,10 → 126,10 |
/** Copy PTE to TLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the entry will be created read-only, regardless |
* of its w field. |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param ro If true, the entry will be created read-only, regardless of its |
* w field. |
*/ |
void dtlb_pte_copy(pte_t *t, index_t index, bool ro) |
{ |
164,8 → 165,8 |
/** Copy PTE to ITLB. |
* |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
* @param t Page Table Entry to be copied. |
* @param index Zero if lower 8K-subpage, one if higher 8K-subpage. |
*/ |
void itlb_pte_copy(pte_t *t, index_t index) |
{ |
234,11 → 235,10 |
* Note that some faults (e.g. kernel faults) were already resolved by the |
* low-level, assembly language part of the fast_data_access_mmu_miss handler. |
* |
* @param tag Content of the TLB Tag Access register as it existed |
* when the trap happened. This is to prevent confusion |
* created by clobbered Tag Access register during a nested |
* DTLB miss. |
* @param istate Interrupted state saved on the stack. |
* @param tag Content of the TLB Tag Access register as it existed when the |
* trap happened. This is to prevent confusion created by clobbered |
* Tag Access register during a nested DTLB miss. |
* @param istate Interrupted state saved on the stack. |
*/ |
void fast_data_access_mmu_miss(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
287,11 → 287,10 |
/** DTLB protection fault handler. |
* |
* @param tag Content of the TLB Tag Access register as it existed |
* when the trap happened. This is to prevent confusion |
* created by clobbered Tag Access register during a nested |
* DTLB miss. |
* @param istate Interrupted state saved on the stack. |
* @param tag Content of the TLB Tag Access register as it existed when the |
* trap happened. This is to prevent confusion created by clobbered |
* Tag Access register during a nested DTLB miss. |
* @param istate Interrupted state saved on the stack. |
*/ |
void fast_data_access_protection(tlb_tag_access_reg_t tag, istate_t *istate) |
{ |
332,26 → 331,6 |
} |
} |
/** Print TLB entry (for debugging purposes). |
* |
* The diag field has been left out in order to make this function more generic |
* (there is no diag field in US3 architeture). |
* |
* @param i TLB entry number |
* @param t TLB entry tag |
* @param d TLB entry data |
*/ |
static void print_tlb_entry(int i, tlb_tag_read_reg_t t, tlb_data_t d) |
{ |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
#if defined (US) |
/** Print contents of both TLBs. */ |
void tlb_print(void) |
{ |
363,7 → 342,12 |
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
t.value = itlb_tag_read_read(i); |
print_tlb_entry(i, t, d); |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
printf("D-TLB contents:\n"); |
370,63 → 354,22 |
for (i = 0; i < DTLB_ENTRY_COUNT; i++) { |
d.value = dtlb_data_access_read(i); |
t.value = dtlb_tag_read_read(i); |
print_tlb_entry(i, t, d); |
printf("%d: vpn=%#llx, context=%d, v=%d, size=%d, nfo=%d, " |
"ie=%d, soft2=%#x, diag=%#x, pfn=%#x, soft=%#x, l=%d, " |
"cp=%d, cv=%d, e=%d, p=%d, w=%d, g=%d\n", i, t.vpn, |
t.context, d.v, d.size, d.nfo, d.ie, d.soft2, d.diag, |
d.pfn, d.soft, d.l, d.cp, d.cv, d.e, d.p, d.w, d.g); |
} |
} |
#elif defined (US3) |
/** Print contents of all TLBs. */ |
void tlb_print(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
printf("TLB_ISMALL contents:\n"); |
for (i = 0; i < tlb_ismall_size(); i++) { |
d.value = dtlb_data_access_read(TLB_ISMALL, i); |
t.value = dtlb_tag_read_read(TLB_ISMALL, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_IBIG contents:\n"); |
for (i = 0; i < tlb_ibig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_IBIG, i); |
t.value = dtlb_tag_read_read(TLB_IBIG, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DSMALL contents:\n"); |
for (i = 0; i < tlb_dsmall_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DSMALL, i); |
t.value = dtlb_tag_read_read(TLB_DSMALL, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DBIG_1 contents:\n"); |
for (i = 0; i < tlb_dbig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DBIG_0, i); |
t.value = dtlb_tag_read_read(TLB_DBIG_0, i); |
print_tlb_entry(i, t, d); |
} |
printf("TLB_DBIG_2 contents:\n"); |
for (i = 0; i < tlb_dbig_size(); i++) { |
d.value = dtlb_data_access_read(TLB_DBIG_1, i); |
t.value = dtlb_tag_read_read(TLB_DBIG_1, i); |
print_tlb_entry(i, t, d); |
} |
} |
#endif |
void do_fast_instruction_access_mmu_miss_fault(istate_t *istate, |
const char *str) |
{ |
fault_if_from_uspace(istate, "%s.", str); |
fault_if_from_uspace(istate, "%s\n", str); |
dump_istate(istate); |
panic("%s.", str); |
panic("%s\n", str); |
} |
void do_fast_data_access_mmu_miss_fault(istate_t *istate, |
436,12 → 379,12 |
va = tag.vpn << MMU_PAGE_WIDTH; |
if (tag.context) { |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va, |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
} |
dump_istate(istate); |
printf("Faulting page: %p, ASID=%d.\n", va, tag.context); |
panic("%s.", str); |
printf("Faulting page: %p, ASID=%d\n", va, tag.context); |
panic("%s\n", str); |
} |
void do_fast_data_access_protection_fault(istate_t *istate, |
452,12 → 395,12 |
va = tag.vpn << MMU_PAGE_WIDTH; |
if (tag.context) { |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d).", str, va, |
fault_if_from_uspace(istate, "%s, Page=%p (ASID=%d)\n", str, va, |
tag.context); |
} |
printf("Faulting page: %p, ASID=%d\n", va, tag.context); |
dump_istate(istate); |
panic("%s.", str); |
panic("%s\n", str); |
} |
void dump_sfsr_and_sfar(void) |
468,71 → 411,30 |
sfsr.value = dtlb_sfsr_read(); |
sfar = dtlb_sfar_read(); |
#if defined (US) |
printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, " |
"fv=%d\n", sfsr.asi, sfsr.ft, sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, |
sfsr.ow, sfsr.fv); |
#elif defined (US3) |
printf("DTLB SFSR: nf=%d, asi=%#x, tm=%d, ft=%#x, e=%d, ct=%d, pr=%d, " |
"w=%d, ow=%d, fv=%d\n", sfsr.nf, sfsr.asi, sfsr.tm, sfsr.ft, |
sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv); |
#endif |
printf("DTLB SFAR: address=%p\n", sfar); |
dtlb_sfsr_write(0); |
} |
#if defined (US3) |
/** Invalidates given TLB entry if and only if it is non-locked or global. |
* |
* @param tlb TLB number (one of TLB_DSMALL, TLB_DBIG_0, TLB_DBIG_1, |
* TLB_ISMALL, TLB_IBIG). |
* @param entry Entry index within the given TLB. |
*/ |
static void tlb_invalidate_entry(int tlb, index_t entry) |
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |
int i; |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
if (tlb == TLB_DSMALL || tlb == TLB_DBIG_0 || tlb == TLB_DBIG_1) { |
d.value = dtlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = dtlb_tag_read_read(tlb, entry); |
d.v = false; |
dtlb_tag_access_write(t.value); |
dtlb_data_access_write(tlb, entry, d.value); |
} |
} else if (tlb == TLB_ISMALL || tlb == TLB_IBIG) { |
d.value = itlb_data_access_read(tlb, entry); |
if (!d.l || d.g) { |
t.value = itlb_tag_read_read(tlb, entry); |
d.v = false; |
itlb_tag_access_write(t.value); |
itlb_data_access_write(tlb, entry, d.value); |
} |
} |
} |
#endif |
/** Invalidate all unlocked ITLB and DTLB entries. */ |
void tlb_invalidate_all(void) |
{ |
int i; |
/* |
* Walk all ITLB and DTLB entries and remove all unlocked mappings. |
* |
* The kernel doesn't use global mappings so any locked global mappings |
* found must have been created by someone else. Their only purpose now |
* found must have been created by someone else. Their only purpose now |
* is to collide with proper mappings. Invalidate immediately. It should |
* be safe to invalidate them as late as now. |
*/ |
#if defined (US) |
tlb_data_t d; |
tlb_tag_read_reg_t t; |
for (i = 0; i < ITLB_ENTRY_COUNT; i++) { |
d.value = itlb_data_access_read(i); |
if (!d.l || d.g) { |
542,7 → 444,7 |
itlb_data_access_write(i, d.value); |
} |
} |
for (i = 0; i < DTLB_ENTRY_COUNT; i++) { |
d.value = dtlb_data_access_read(i); |
if (!d.l || d.g) { |
552,21 → 454,7 |
dtlb_data_access_write(i, d.value); |
} |
} |
#elif defined (US3) |
for (i = 0; i < tlb_ismall_size(); i++) |
tlb_invalidate_entry(TLB_ISMALL, i); |
for (i = 0; i < tlb_ibig_size(); i++) |
tlb_invalidate_entry(TLB_IBIG, i); |
for (i = 0; i < tlb_dsmall_size(); i++) |
tlb_invalidate_entry(TLB_DSMALL, i); |
for (i = 0; i < tlb_dbig_size(); i++) |
tlb_invalidate_entry(TLB_DBIG_0, i); |
for (i = 0; i < tlb_dbig_size(); i++) |
tlb_invalidate_entry(TLB_DBIG_1, i); |
#endif |
} |
/** Invalidate all ITLB and DTLB entries that belong to specified ASID |
596,9 → 484,9 |
/** Invalidate all ITLB and DTLB entries for specified page range in specified |
* address space. |
* |
* @param asid Address Space ID. |
* @param page First page which to sweep out from ITLB and DTLB. |
* @param cnt Number of ITLB and DTLB entries to invalidate. |
* @param asid Address Space ID. |
* @param page First page which to sweep out from ITLB and DTLB. |
* @param cnt Number of ITLB and DTLB entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
/branches/dd/kernel/arch/sparc64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
79,6 → 79,7 |
*/ |
frame_mark_unavailable(ADDR2PFN(KA2PA(PFN2ADDR(0))), 1); |
} |
} |
/** @} |
/branches/dd/kernel/arch/sparc64/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sparc64mm |
/** @addtogroup sparc64mm |
* @{ |
*/ |
/** @file |
52,7 → 52,7 |
uintptr_t virt_page; |
uintptr_t phys_page; |
int pagesize_code; |
} bsp_locked_dtlb_entry[DTLB_MAX_LOCKED_ENTRIES]; |
} bsp_locked_dtlb_entry[DTLB_ENTRY_COUNT]; |
/** Number of entries in bsp_locked_dtlb_entry array. */ |
static count_t bsp_locked_dtlb_entries = 0; |
147,7 → 147,7 |
physaddr + i * sizemap[order].increment, |
sizemap[order].pagesize_code, true, false); |
#ifdef CONFIG_SMP |
#ifdef CONFIG_SMP |
/* |
* Second, save the information about the mapping for APs. |
*/ |
/branches/dd/kernel/arch/sparc64/src/mm/as.c |
---|
76,7 → 76,7 |
as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * |
sizeof(tsb_entry_t)); |
memsetb(as->arch.itsb, |
memsetb((uintptr_t) as->arch.itsb, |
(ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); |
#endif |
return 0; |
164,25 → 164,7 |
itsb_base_write(tsb_base.value); |
tsb_base.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; |
dtsb_base_write(tsb_base.value); |
#if defined (US3) |
/* |
* Clear the extension registers. |
* In HelenOS, primary and secondary context registers contain |
* equal values and kernel misses (context 0, ie. the nucleus context) |
* are excluded from the TSB miss handler, so it makes no sense |
* to have separate TSBs for primary, secondary and nucleus contexts. |
* Clearing the extension registers will ensure that the value of the |
* TSB Base register will be used as an address of TSB, making the code |
* compatible with the US port. |
*/ |
itsb_primary_extension_write(0); |
itsb_nucleus_extension_write(0); |
dtsb_primary_extension_write(0); |
dtsb_secondary_extension_write(0); |
dtsb_nucleus_extension_write(0); |
#endif |
#endif |
} |
/** Perform sparc64-specific tasks when an address space is removed from the |
/branches/dd/kernel/arch/sparc64/src/mm/tsb.c |
---|
112,9 → 112,9 |
tsb->data.value = 0; |
tsb->data.size = PAGESIZE_8K; |
tsb->data.pfn = (t->frame >> MMU_FRAME_WIDTH) + index; |
tsb->data.cp = t->c; /* cp as cache in phys.-idxed, c as cacheable */ |
tsb->data.p = t->k; /* p as privileged, k as kernel */ |
tsb->data.v = t->p; /* v as valid, p as present */ |
tsb->data.cp = t->c; |
tsb->data.p = t->k; /* p as privileged */ |
tsb->data.v = t->p; |
write_barrier(); |
173,4 → 173,3 |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/src/mm/cache.S |
---|
27,8 → 27,10 |
*/ |
#include <arch/arch.h> |
#include <arch/mm/cache_spec.h> |
#define DCACHE_SIZE (16 * 1024) |
#define DCACHE_LINE_SIZE 32 |
#define DCACHE_TAG_SHIFT 2 |
.register %g2, #scratch |
47,3 → 49,45 |
retl |
! beware SF Erratum #51, do not put the MEMBAR here |
nop |
/** Flush only D-cache lines of one virtual color. |
* |
* @param o0 Virtual color to be flushed. |
*/ |
.global dcache_flush_color |
dcache_flush_color: |
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1 |
set DCACHE_SIZE / 2, %g2 |
sllx %g2, %o0, %g2 |
sub %g2, DCACHE_LINE_SIZE, %g2 |
0: stxa %g0, [%g2] ASI_DCACHE_TAG |
membar #Sync |
subcc %g1, 1, %g1 |
bnz,pt %xcc, 0b |
sub %g2, DCACHE_LINE_SIZE, %g2 |
retl |
nop |
/** Flush only D-cache lines of one virtual color and one tag. |
* |
* @param o0 Virtual color to lookup the tag. |
* @param o1 Tag of the cachelines to be flushed. |
*/ |
.global dcache_flush_tag |
dcache_flush_tag: |
mov (DCACHE_SIZE / DCACHE_LINE_SIZE) / 2, %g1 |
set DCACHE_SIZE / 2, %g2 |
sllx %g2, %o0, %g2 |
sub %g2, DCACHE_LINE_SIZE, %g2 |
0: ldxa [%g2] ASI_DCACHE_TAG, %g3 |
srlx %g3, DCACHE_TAG_SHIFT, %g3 |
cmp %g3, %o1 |
bnz 1f |
nop |
stxa %g0, [%g2] ASI_DCACHE_TAG |
membar #Sync |
1: subcc %g1, 1, %g1 |
bnz,pt %xcc, 0b |
sub %g2, DCACHE_LINE_SIZE, %g2 |
retl |
nop |
/branches/dd/kernel/arch/sparc64/src/trap/trap_table.S |
---|
329,22 → 329,198 |
fill_1_normal_tl0: |
FILL_NORMAL_HANDLER_USERSPACE |
/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */ |
.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\ |
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\ |
39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\ |
58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\ |
77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\ |
96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\ |
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\ |
127 |
.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE |
.global trap_instruction_\cur\()_tl0 |
trap_instruction_\cur\()_tl0: |
ba trap_instruction_handler |
mov \cur, %g2 |
.endr |
/* TT = 0x100, TL = 0, trap_instruction_0 */ |
.org trap_table + TT_TRAP_INSTRUCTION(0)*ENTRY_SIZE |
.global trap_instruction_0_tl0 |
trap_instruction_0_tl0: |
TRAP_INSTRUCTION 0 |
/* TT = 0x101, TL = 0, trap_instruction_1 */ |
.org trap_table + TT_TRAP_INSTRUCTION(1)*ENTRY_SIZE |
.global trap_instruction_1_tl0 |
trap_instruction_1_tl0: |
TRAP_INSTRUCTION 1 |
/* TT = 0x102, TL = 0, trap_instruction_2 */ |
.org trap_table + TT_TRAP_INSTRUCTION(2)*ENTRY_SIZE |
.global trap_instruction_2_tl0 |
trap_instruction_2_tl0: |
TRAP_INSTRUCTION 2 |
/* TT = 0x103, TL = 0, trap_instruction_3 */ |
.org trap_table + TT_TRAP_INSTRUCTION(3)*ENTRY_SIZE |
.global trap_instruction_3_tl0 |
trap_instruction_3_tl0: |
TRAP_INSTRUCTION 3 |
/* TT = 0x104, TL = 0, trap_instruction_4 */ |
.org trap_table + TT_TRAP_INSTRUCTION(4)*ENTRY_SIZE |
.global trap_instruction_4_tl0 |
trap_instruction_4_tl0: |
TRAP_INSTRUCTION 4 |
/* TT = 0x105, TL = 0, trap_instruction_5 */ |
.org trap_table + TT_TRAP_INSTRUCTION(5)*ENTRY_SIZE |
.global trap_instruction_5_tl0 |
trap_instruction_5_tl0: |
TRAP_INSTRUCTION 5 |
/* TT = 0x106, TL = 0, trap_instruction_6 */ |
.org trap_table + TT_TRAP_INSTRUCTION(6)*ENTRY_SIZE |
.global trap_instruction_6_tl0 |
trap_instruction_6_tl0: |
TRAP_INSTRUCTION 6 |
/* TT = 0x107, TL = 0, trap_instruction_7 */ |
.org trap_table + TT_TRAP_INSTRUCTION(7)*ENTRY_SIZE |
.global trap_instruction_7_tl0 |
trap_instruction_7_tl0: |
TRAP_INSTRUCTION 7 |
/* TT = 0x108, TL = 0, trap_instruction_8 */ |
.org trap_table + TT_TRAP_INSTRUCTION(8)*ENTRY_SIZE |
.global trap_instruction_8_tl0 |
trap_instruction_8_tl0: |
TRAP_INSTRUCTION 8 |
/* TT = 0x109, TL = 0, trap_instruction_9 */ |
.org trap_table + TT_TRAP_INSTRUCTION(9)*ENTRY_SIZE |
.global trap_instruction_9_tl0 |
trap_instruction_9_tl0: |
TRAP_INSTRUCTION 9 |
/* TT = 0x10a, TL = 0, trap_instruction_10 */ |
.org trap_table + TT_TRAP_INSTRUCTION(10)*ENTRY_SIZE |
.global trap_instruction_10_tl0 |
trap_instruction_10_tl0: |
TRAP_INSTRUCTION 10 |
/* TT = 0x10b, TL = 0, trap_instruction_11 */ |
.org trap_table + TT_TRAP_INSTRUCTION(11)*ENTRY_SIZE |
.global trap_instruction_11_tl0 |
trap_instruction_11_tl0: |
TRAP_INSTRUCTION 11 |
/* TT = 0x10c, TL = 0, trap_instruction_12 */ |
.org trap_table + TT_TRAP_INSTRUCTION(12)*ENTRY_SIZE |
.global trap_instruction_12_tl0 |
trap_instruction_12_tl0: |
TRAP_INSTRUCTION 12 |
/* TT = 0x10d, TL = 0, trap_instruction_13 */ |
.org trap_table + TT_TRAP_INSTRUCTION(13)*ENTRY_SIZE |
.global trap_instruction_13_tl0 |
trap_instruction_13_tl0: |
TRAP_INSTRUCTION 13 |
/* TT = 0x10e, TL = 0, trap_instruction_14 */ |
.org trap_table + TT_TRAP_INSTRUCTION(14)*ENTRY_SIZE |
.global trap_instruction_14_tl0 |
trap_instruction_14_tl0: |
TRAP_INSTRUCTION 14 |
/* TT = 0x10f, TL = 0, trap_instruction_15 */ |
.org trap_table + TT_TRAP_INSTRUCTION(15)*ENTRY_SIZE |
.global trap_instruction_15_tl0 |
trap_instruction_15_tl0: |
TRAP_INSTRUCTION 15 |
/* TT = 0x110, TL = 0, trap_instruction_16 */ |
.org trap_table + TT_TRAP_INSTRUCTION(16)*ENTRY_SIZE |
.global trap_instruction_16_tl0 |
trap_instruction_16_tl0: |
TRAP_INSTRUCTION 16 |
/* TT = 0x111, TL = 0, trap_instruction_17 */ |
.org trap_table + TT_TRAP_INSTRUCTION(17)*ENTRY_SIZE |
.global trap_instruction_17_tl0 |
trap_instruction_17_tl0: |
TRAP_INSTRUCTION 17 |
/* TT = 0x112, TL = 0, trap_instruction_18 */ |
.org trap_table + TT_TRAP_INSTRUCTION(18)*ENTRY_SIZE |
.global trap_instruction_18_tl0 |
trap_instruction_18_tl0: |
TRAP_INSTRUCTION 18 |
/* TT = 0x113, TL = 0, trap_instruction_19 */ |
.org trap_table + TT_TRAP_INSTRUCTION(19)*ENTRY_SIZE |
.global trap_instruction_19_tl0 |
trap_instruction_19_tl0: |
TRAP_INSTRUCTION 19 |
/* TT = 0x114, TL = 0, trap_instruction_20 */ |
.org trap_table + TT_TRAP_INSTRUCTION(20)*ENTRY_SIZE |
.global trap_instruction_20_tl0 |
trap_instruction_20_tl0: |
TRAP_INSTRUCTION 20 |
/* TT = 0x115, TL = 0, trap_instruction_21 */ |
.org trap_table + TT_TRAP_INSTRUCTION(21)*ENTRY_SIZE |
.global trap_instruction_21_tl0 |
trap_instruction_21_tl0: |
TRAP_INSTRUCTION 21 |
/* TT = 0x116, TL = 0, trap_instruction_22 */ |
.org trap_table + TT_TRAP_INSTRUCTION(22)*ENTRY_SIZE |
.global trap_instruction_22_tl0 |
trap_instruction_22_tl0: |
TRAP_INSTRUCTION 22 |
/* TT = 0x117, TL = 0, trap_instruction_23 */ |
.org trap_table + TT_TRAP_INSTRUCTION(23)*ENTRY_SIZE |
.global trap_instruction_23_tl0 |
trap_instruction_23_tl0: |
TRAP_INSTRUCTION 23 |
/* TT = 0x118, TL = 0, trap_instruction_24 */ |
.org trap_table + TT_TRAP_INSTRUCTION(24)*ENTRY_SIZE |
.global trap_instruction_24_tl0 |
trap_instruction_24_tl0: |
TRAP_INSTRUCTION 24 |
/* TT = 0x119, TL = 0, trap_instruction_25 */ |
.org trap_table + TT_TRAP_INSTRUCTION(25)*ENTRY_SIZE |
.global trap_instruction_25_tl0 |
trap_instruction_25_tl0: |
TRAP_INSTRUCTION 25 |
/* TT = 0x11a, TL = 0, trap_instruction_26 */ |
.org trap_table + TT_TRAP_INSTRUCTION(26)*ENTRY_SIZE |
.global trap_instruction_26_tl0 |
trap_instruction_26_tl0: |
TRAP_INSTRUCTION 26 |
/* TT = 0x11b, TL = 0, trap_instruction_27 */ |
.org trap_table + TT_TRAP_INSTRUCTION(27)*ENTRY_SIZE |
.global trap_instruction_27_tl0 |
trap_instruction_27_tl0: |
TRAP_INSTRUCTION 27 |
/* TT = 0x11c, TL = 0, trap_instruction_28 */ |
.org trap_table + TT_TRAP_INSTRUCTION(28)*ENTRY_SIZE |
.global trap_instruction_28_tl0 |
trap_instruction_28_tl0: |
TRAP_INSTRUCTION 28 |
/* TT = 0x11d, TL = 0, trap_instruction_29 */ |
.org trap_table + TT_TRAP_INSTRUCTION(29)*ENTRY_SIZE |
.global trap_instruction_29_tl0 |
trap_instruction_29_tl0: |
TRAP_INSTRUCTION 29 |
/* TT = 0x11e, TL = 0, trap_instruction_30 */ |
.org trap_table + TT_TRAP_INSTRUCTION(30)*ENTRY_SIZE |
.global trap_instruction_30_tl0 |
trap_instruction_30_tl0: |
TRAP_INSTRUCTION 30 |
/* TT = 0x11f, TL = 0, trap_instruction_31 */ |
.org trap_table + TT_TRAP_INSTRUCTION(31)*ENTRY_SIZE |
.global trap_instruction_31_tl0 |
trap_instruction_31_tl0: |
TRAP_INSTRUCTION 31 |
/* |
* Handlers for TL>0. |
*/ |
606,10 → 782,10 |
add %sp, PREEMPTIBLE_HANDLER_STACK_FRAME_SIZE + STACK_BIAS + SAVED_TNPC, %o1 |
.else |
/* |
* Call the higher-level syscall handler and enable interrupts. |
* Call the higher-level syscall handler. |
*/ |
call syscall_handler |
wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate |
nop |
mov %o0, %i0 ! copy the value returned by the syscall |
.endif |
748,8 → 924,9 |
* Fill all windows stored in the buffer. |
*/ |
clr %g4 |
0: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check |
bz 0f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill |
set PAGE_SIZE - 1, %g5 |
0: andcc %g7, %g5, %g0 ! PAGE_SIZE alignment check |
bz 0f ! %g7 is page-aligned, no more windows to refill |
nop |
add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7 |
/branches/dd/kernel/arch/sparc64/src/trap/exception.c |
---|
45,57 → 45,57 |
void dump_istate(istate_t *istate) |
{ |
printf("TSTATE=%#" PRIx64 "\n", istate->tstate); |
printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, get_symtab_entry(istate->tpc)); |
printf("TNPC=%#" PRIx64 " (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc)); |
printf("TSTATE=%#llx\n", istate->tstate); |
printf("TPC=%#llx (%s)\n", istate->tpc, get_symtab_entry(istate->tpc)); |
printf("TNPC=%#llx (%s)\n", istate->tnpc, get_symtab_entry(istate->tnpc)); |
} |
/** Handle instruction_access_exception. (0x8) */ |
void instruction_access_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle instruction_access_error. (0xa) */ |
void instruction_access_error(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle illegal_instruction. (0x10) */ |
void illegal_instruction(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle privileged_opcode. (0x11) */ |
void privileged_opcode(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle unimplemented_LDD. (0x12) */ |
void unimplemented_LDD(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle unimplemented_STD. (0x13) */ |
void unimplemented_STD(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle fp_disabled. (0x20) */ |
113,9 → 113,9 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
#endif |
} |
122,98 → 122,98 |
/** Handle fp_exception_ieee_754. (0x21) */ |
void fp_exception_ieee_754(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle fp_exception_other. (0x22) */ |
void fp_exception_other(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle tag_overflow. (0x23) */ |
void tag_overflow(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle division_by_zero. (0x28) */ |
void division_by_zero(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle data_access_exception. (0x30) */ |
void data_access_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
dump_sfsr_and_sfar(); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle data_access_error. (0x32) */ |
void data_access_error(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle mem_address_not_aligned. (0x34) */ |
void mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle LDDF_mem_address_not_aligned. (0x35) */ |
void LDDF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle STDF_mem_address_not_aligned. (0x36) */ |
void STDF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle privileged_action. (0x37) */ |
void privileged_action(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle LDQF_mem_address_not_aligned. (0x38) */ |
void LDQF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Handle STQF_mem_address_not_aligned. (0x39) */ |
void STQF_mem_address_not_aligned(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "%s.", __func__); |
fault_if_from_uspace(istate, "%s\n", __func__); |
dump_istate(istate); |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** @} |
/branches/dd/kernel/arch/sparc64/src/trap/interrupt.c |
---|
67,19 → 67,11 |
*/ |
void interrupt(int n, istate_t *istate) |
{ |
uint64_t status; |
uint64_t intrcv; |
uint64_t data0; |
status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); |
if (status & (!INTR_DISPATCH_STATUS_BUSY)) |
panic("Interrupt Dispatch Status busy bit not set."); |
intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0); |
#if defined (US) |
data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0); |
#elif defined (US3) |
data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0); |
#endif |
data0 = asi_u64_read(ASI_UDB_INTR_R, ASI_UDB_INTR_R_DATA_0); |
irq_t *irq = irq_dispatch_and_lock(data0); |
if (irq) { |
86,13 → 78,7 |
/* |
* The IRQ handler was found. |
*/ |
irq->handler(irq); |
/* |
* See if there is a clear-interrupt-routine and call it. |
*/ |
if (irq->cir) { |
irq->cir(irq->cir_arg, irq->inr); |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else if (data0 > config.base) { |
/* |
111,8 → 97,8 |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64 |
", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); |
printf("cpu%d: spurious interrupt (intrcv=%#llx, " |
"data0=%#llx)\n", CPU->id, intrcv, data0); |
#endif |
} |
/branches/dd/kernel/arch/sparc64/src/drivers/sgcn.c |
---|
File deleted |
/branches/dd/kernel/arch/sparc64/src/drivers/scr.c |
---|
37,7 → 37,7 |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <arch/types.h> |
#include <string.h> |
#include <func.h> |
#include <align.h> |
#include <print.h> |
55,10 → 55,6 |
void scr_init(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
ofw_pci_reg_t *pci_reg; |
ofw_pci_reg_t pci_abs_reg; |
ofw_upa_reg_t *upa_reg; |
ofw_sbus_reg_t *sbus_reg; |
const char *name; |
name = ofw_tree_node_name(node); |
65,8 → 61,6 |
if (strcmp(name, "SUNW,m64B") == 0) |
scr_type = SCR_ATYFB; |
else if (strcmp(name, "SUNW,XVR-100") == 0) |
scr_type = SCR_XVR; |
else if (strcmp(name, "SUNW,ffb") == 0) |
scr_type = SCR_FFB; |
else if (strcmp(name, "cgsix") == 0) |
73,12 → 67,11 |
scr_type = SCR_CGSIX; |
if (scr_type == SCR_UNKNOWN) { |
printf("Unknown screen device.\n"); |
printf("Unknown keyboard device.\n"); |
return; |
} |
uintptr_t fb_addr; |
unsigned int fb_offset = 0; |
uint32_t fb_width = 0; |
uint32_t fb_height = 0; |
uint32_t fb_depth = 0; |
104,7 → 97,7 |
prop = ofw_tree_getprop(node, "reg"); |
if (!prop) |
panic("Cannot find 'reg' property."); |
panic("Can't find \"reg\" property.\n"); |
switch (scr_type) { |
case SCR_ATYFB: |
113,15 → 106,15 |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t *fb_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
ofw_pci_reg_t abs_reg; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
if (!ofw_pci_reg_absolutize(node, fb_reg, &abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
if (!ofw_pci_apply_ranges(node->parent, &abs_reg , &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
149,56 → 142,12 |
} |
break; |
case SCR_XVR: |
if (prop->size / sizeof(ofw_pci_reg_t) < 2) { |
printf("Too few screen registers.\n"); |
return; |
} |
pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; |
if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { |
printf("Failed to absolutize fb register.\n"); |
return; |
} |
if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, |
&fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
fb_offset = 4 * 0x2000; |
switch (fb_depth) { |
case 8: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_INDIRECT_8; |
break; |
case 16: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_5_6_5; |
break; |
case 24: |
fb_scanline = fb_linebytes * 4; |
visual = VISUAL_RGB_8_8_8_0; |
break; |
case 32: |
fb_scanline = fb_linebytes * (fb_depth >> 3); |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
printf("Unsupported bits per pixel.\n"); |
return; |
} |
break; |
case SCR_FFB: |
fb_scanline = 8192; |
visual = VISUAL_BGR_0_8_8_8; |
upa_reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, upa_reg, &fb_addr)) { |
ofw_upa_reg_t *reg = &((ofw_upa_reg_t *) prop->value)[FFB_REG_24BPP]; |
if (!ofw_upa_apply_ranges(node->parent, reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
215,8 → 164,8 |
return; |
} |
sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) { |
ofw_sbus_reg_t *cg6_reg = &((ofw_sbus_reg_t *) prop->value)[0]; |
if (!ofw_sbus_apply_ranges(node->parent, cg6_reg, &fb_addr)) { |
printf("Failed to determine screen address.\n"); |
return; |
} |
223,24 → 172,11 |
break; |
default: |
panic("Unexpected type."); |
panic("Unexpected type.\n"); |
} |
fb_properties_t props = { |
.addr = fb_addr, |
.offset = fb_offset, |
.x = fb_width, |
.y = fb_height, |
.scan = fb_scanline, |
.visual = visual, |
}; |
fb_init(&props); |
fb_init(fb_addr, fb_width, fb_height, fb_scanline, visual); |
} |
void scr_redraw(void) |
{ |
fb_redraw(); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/src/drivers/tick.c |
---|
45,12 → 45,11 |
#define TICK_RESTART_TIME 50 /* Worst case estimate. */ |
/** Initialize tick and stick interrupt. */ |
/** Initialize tick interrupt. */ |
void tick_init(void) |
{ |
/* initialize TICK interrupt */ |
tick_compare_reg_t compare; |
interrupt_register(14, "tick_int", tick_interrupt); |
compare.int_dis = false; |
compare.tick_cmpr = CPU->arch.clock_frequency / HZ; |
57,21 → 56,6 |
CPU->arch.next_tick_cmpr = compare.tick_cmpr; |
tick_compare_write(compare.value); |
tick_write(0); |
#if defined (US3) |
/* disable STICK interrupts and clear any pending ones */ |
tick_compare_reg_t stick_compare; |
softint_reg_t clear; |
stick_compare.value = stick_compare_read(); |
stick_compare.int_dis = true; |
stick_compare.tick_cmpr = 0; |
stick_compare_write(stick_compare.value); |
clear.value = 0; |
clear.stick_int = 1; |
clear_softint_write(clear.value); |
#endif |
} |
/** Process tick interrupt. |
83,7 → 67,7 |
{ |
softint_reg_t softint, clear; |
uint64_t drift; |
softint.value = softint_read(); |
/* |
/branches/dd/kernel/arch/sparc64/src/drivers/fhc.c |
---|
45,7 → 45,6 |
#include <mm/slab.h> |
#include <arch/types.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <sysinfo/sysinfo.h> |
fhc_t *central_fhc = NULL; |
87,13 → 86,6 |
fhc->uart_imap = (uint32_t *) hw_map(paddr, reg->size); |
/* |
* Set sysinfo data needed by the uspace FHC driver. |
*/ |
sysinfo_set_item_val("fhc.uart.size", NULL, reg->size); |
sysinfo_set_item_val("fhc.uart.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.fhc", NULL, 1); |
return fhc; |
} |
104,14 → 96,13 |
fhc->uart_imap[FHC_UART_IMAP] |= IMAP_V_MASK; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
void fhc_clear_interrupt(void *fhcp, int inr) |
void fhc_clear_interrupt(fhc_t *fhc, int inr) |
{ |
fhc_t *fhc = (fhc_t *)fhcp; |
ASSERT(fhc->uart_imap); |
switch (inr) { |
119,7 → 110,7 |
fhc->uart_imap[FHC_UART_ICLR] = 0; |
break; |
default: |
panic("Unexpected INR (%d).", inr); |
panic("Unexpected INR (%d)\n", inr); |
break; |
} |
} |
/branches/dd/kernel/arch/sparc64/src/drivers/kbd.c |
---|
34,26 → 34,19 |
#include <arch/drivers/kbd.h> |
#include <genarch/ofw/ofw_tree.h> |
#ifdef CONFIG_SUN_KBD |
#include <genarch/kbrd/kbrd.h> |
#endif |
#ifdef CONFIG_Z8530 |
#include <genarch/drivers/z8530/z8530.h> |
#include <genarch/kbd/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/drivers/ns16550/ns16550.h> |
#include <genarch/kbd/ns16550.h> |
#endif |
#include <console/console.h> |
#include <ddi/device.h> |
#include <ddi/irq.h> |
#include <arch/mm/page.h> |
#include <arch/types.h> |
#include <align.h> |
#include <string.h> |
#include <func.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
kbd_type_t kbd_type = KBD_UNKNOWN; |
70,15 → 63,6 |
uintptr_t aligned_addr; |
ofw_tree_property_t *prop; |
const char *name; |
cir_t cir; |
void *cir_arg; |
#ifdef CONFIG_NS16550 |
ns16550_t *ns16550; |
#endif |
#ifdef CONFIG_Z8530 |
z8530_t *z8530; |
#endif |
name = ofw_tree_node_name(node); |
100,33 → 84,30 |
*/ |
uint32_t interrupts; |
prop = ofw_tree_getprop(node, "interrupts"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'interrupt' property."); |
if (!prop || !prop->value) |
panic("Can't find \"interrupts\" property.\n"); |
interrupts = *((uint32_t *) prop->value); |
/* |
* Read 'reg' property. |
*/ |
prop = ofw_tree_getprop(node, "reg"); |
if ((!prop) || (!prop->value)) |
panic("Cannot find 'reg' property."); |
if (!prop || !prop->value) |
panic("Can't find \"reg\" property.\n"); |
uintptr_t pa; |
size_t size; |
devno_t devno; |
inr_t inr; |
devno_t devno = device_assign_devno(); |
switch (kbd_type) { |
case KBD_Z8530: |
size = ((ofw_fhc_reg_t *) prop->value)->size; |
if (!ofw_fhc_apply_ranges(node->parent, |
((ofw_fhc_reg_t *) prop->value), &pa)) { |
if (!ofw_fhc_apply_ranges(node->parent, ((ofw_fhc_reg_t *) prop->value) , &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_fhc_map_interrupt(node->parent, |
((ofw_fhc_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
if (!ofw_fhc_map_interrupt(node->parent, ((ofw_fhc_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
} |
134,20 → 115,18 |
case KBD_NS16550: |
size = ((ofw_ebus_reg_t *) prop->value)->size; |
if (!ofw_ebus_apply_ranges(node->parent, |
((ofw_ebus_reg_t *) prop->value), &pa)) { |
if (!ofw_ebus_apply_ranges(node->parent, ((ofw_ebus_reg_t *) prop->value) , &pa)) { |
printf("Failed to determine keyboard address.\n"); |
return; |
} |
if (!ofw_ebus_map_interrupt(node->parent, |
((ofw_ebus_reg_t *) prop->value), interrupts, &inr, &cir, |
&cir_arg)) { |
if (!ofw_ebus_map_interrupt(node->parent, ((ofw_ebus_reg_t *) prop->value), interrupts, &inr)) { |
printf("Failed to determine keyboard interrupt.\n"); |
return; |
}; |
break; |
default: |
panic("Unexpected keyboard type."); |
panic("Unexpected type.\n"); |
} |
/* |
158,53 → 137,21 |
*/ |
aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); |
offset = pa - aligned_addr; |
uintptr_t vaddr = hw_map(aligned_addr, offset + size) + offset; |
switch (kbd_type) { |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
devno = device_assign_devno(); |
z8530 = (z8530_t *) hw_map(aligned_addr, offset + size) + |
offset; |
kbrd_init(stdin); |
(void) z8530_init(z8530, devno, inr, cir, cir_arg, &kbrdin); |
/* |
* This is the necessary evil until the userspace drivers are |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) z8530); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
z8530_init(devno, inr, vaddr); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
devno = device_assign_devno(); |
ns16550 = (ns16550_t *) hw_map(aligned_addr, offset + size) + |
offset; |
kbrd_init(stdin); |
(void) ns16550_init(ns16550, devno, inr, cir, cir_arg, &kbrdin); |
/* |
* This is the necessary evil until the userspace driver is |
* entirely self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) ns16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, pa); |
ns16550_init(devno, inr, vaddr); |
break; |
#endif |
default: |
printf("Kernel is not compiled with the necessary keyboard " |
"driver this machine requires.\n"); |
printf("Kernel is not compiled with the necessary keyboard driver this machine requires.\n"); |
} |
} |
/branches/dd/kernel/arch/sparc64/src/drivers/pci.c |
---|
42,41 → 42,43 |
#include <arch/types.h> |
#include <debug.h> |
#include <print.h> |
#include <string.h> |
#include <func.h> |
#include <arch/asm.h> |
#include <sysinfo/sysinfo.h> |
#define SABRE_INTERNAL_REG 0 |
#define PSYCHO_INTERNAL_REG 2 |
#define PCI_SABRE_REGS_REG 0 |
#define OBIO_IMR_BASE 0x200 |
#define OBIO_IMR(ino) (OBIO_IMR_BASE + ((ino) & INO_MASK)) |
#define PCI_SABRE_IMAP_BASE 0x200 |
#define PCI_SABRE_ICLR_BASE 0x300 |
#define OBIO_CIR_BASE 0x300 |
#define OBIO_CIR(ino) (OBIO_CIR_BASE + ((ino) & INO_MASK)) |
#define PCI_PSYCHO_REGS_REG 2 |
static void obio_enable_interrupt(pci_t *, int); |
static void obio_clear_interrupt(pci_t *, int); |
#define PCI_PSYCHO_IMAP_BASE 0x200 |
#define PCI_PSYCHO_ICLR_BASE 0x300 |
static pci_t *pci_sabre_init(ofw_tree_node_t *); |
static pci_t *pci_psycho_init(ofw_tree_node_t *); |
static pci_t *pci_sabre_init(ofw_tree_node_t *node); |
static void pci_sabre_enable_interrupt(pci_t *pci, int inr); |
static void pci_sabre_clear_interrupt(pci_t *pci, int inr); |
static pci_t *pci_psycho_init(ofw_tree_node_t *node); |
static void pci_psycho_enable_interrupt(pci_t *pci, int inr); |
static void pci_psycho_clear_interrupt(pci_t *pci, int inr); |
/** PCI operations for Sabre model. */ |
static pci_operations_t pci_sabre_ops = { |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_sabre_enable_interrupt, |
.clear_interrupt = pci_sabre_clear_interrupt |
}; |
/** PCI operations for Psycho model. */ |
static pci_operations_t pci_psycho_ops = { |
.enable_interrupt = obio_enable_interrupt, |
.clear_interrupt = obio_clear_interrupt |
.enable_interrupt = pci_psycho_enable_interrupt, |
.clear_interrupt = pci_psycho_clear_interrupt |
}; |
/** Initialize PCI controller (model Sabre). |
* |
* @param node OpenFirmware device tree node of the Sabre. |
* @param node OpenFirmware device tree node of the Sabre. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_sabre_init(ofw_tree_node_t *node) |
{ |
93,12 → 95,11 |
ofw_upa_reg_t *reg = prop->value; |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < SABRE_INTERNAL_REG + 1) |
if (regs < PCI_SABRE_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[SABRE_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_SABRE_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
107,14 → 108,8 |
pci->model = PCI_SABRE; |
pci->op = &pci_sabre_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[SABRE_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_SABRE_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
121,9 → 116,9 |
/** Initialize the Psycho PCI controller. |
* |
* @param node OpenFirmware device tree node of the Psycho. |
* @param node OpenFirmware device tree node of the Psycho. |
* |
* @return Address of the initialized PCI structure. |
* @return Address of the initialized PCI structure. |
*/ |
pci_t *pci_psycho_init(ofw_tree_node_t *node) |
{ |
140,12 → 135,11 |
ofw_upa_reg_t *reg = prop->value; |
count_t regs = prop->size / sizeof(ofw_upa_reg_t); |
if (regs < PSYCHO_INTERNAL_REG + 1) |
if (regs < PCI_PSYCHO_REGS_REG + 1) |
return NULL; |
uintptr_t paddr; |
if (!ofw_upa_apply_ranges(node->parent, ®[PSYCHO_INTERNAL_REG], |
&paddr)) |
if (!ofw_upa_apply_ranges(node->parent, ®[PCI_PSYCHO_REGS_REG], &paddr)) |
return NULL; |
pci = (pci_t *) malloc(sizeof(pci_t), FRAME_ATOMIC); |
154,27 → 148,31 |
pci->model = PCI_PSYCHO; |
pci->op = &pci_psycho_ops; |
pci->reg = (uint64_t *) hw_map(paddr, reg[PSYCHO_INTERNAL_REG].size); |
pci->reg = (uint64_t *) hw_map(paddr, reg[PCI_PSYCHO_REGS_REG].size); |
/* |
* Set sysinfo data needed by the uspace OBIO driver. |
*/ |
sysinfo_set_item_val("obio.base.physical", NULL, paddr); |
sysinfo_set_item_val("kbd.cir.obio", NULL, 1); |
return pci; |
} |
void obio_enable_interrupt(pci_t *pci, int inr) |
void pci_sabre_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_IMR(inr & INO_MASK)] |= IMAP_V_MASK; |
pci->reg[PCI_SABRE_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void obio_clear_interrupt(pci_t *pci, int inr) |
void pci_sabre_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[OBIO_CIR(inr & INO_MASK)] = 0; /* set IDLE */ |
pci->reg[PCI_SABRE_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
void pci_psycho_enable_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_IMAP_BASE + (inr & INO_MASK)] |= IMAP_V_MASK; |
} |
void pci_psycho_clear_interrupt(pci_t *pci, int inr) |
{ |
pci->reg[PCI_PSYCHO_ICLR_BASE + (inr & INO_MASK)] = 0; |
} |
/** Initialize PCI controller. */ |
pci_t *pci_init(ofw_tree_node_t *node) |
{ |
217,14 → 215,14 |
void pci_enable_interrupt(pci_t *pci, int inr) |
{ |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->enable_interrupt); |
pci->op->enable_interrupt(pci, inr); |
} |
void pci_clear_interrupt(void *pcip, int inr) |
void pci_clear_interrupt(pci_t *pci, int inr) |
{ |
pci_t *pci = (pci_t *)pcip; |
ASSERT(pci->model); |
ASSERT(pci->op && pci->op->clear_interrupt); |
pci->op->clear_interrupt(pci, inr); |
} |
/branches/dd/kernel/arch/sparc64/src/proc/thread.c |
---|
34,8 → 34,9 |
#include <proc/thread.h> |
#include <arch/proc/thread.h> |
#include <mm/slab.h> |
#include <arch/trap/regwin.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <arch/mm/page.h> |
#include <align.h> |
void thr_constructor_arch(thread_t *t) |
49,12 → 50,12 |
void thr_destructor_arch(thread_t *t) |
{ |
if (t->arch.uspace_window_buffer) { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
/* |
* Mind the possible alignment of the userspace window buffer |
* belonging to a killed thread. |
*/ |
free((uint8_t *) ALIGN_DOWN(uw_buf, UWB_ALIGNMENT)); |
frame_free(KA2PA(ALIGN_DOWN((uintptr_t) |
t->arch.uspace_window_buffer, PAGE_SIZE))); |
} |
} |
66,7 → 67,7 |
* The thread needs userspace window buffer and the object |
* returned from the slab allocator doesn't have any. |
*/ |
t->arch.uspace_window_buffer = malloc(UWB_ASIZE, 0); |
t->arch.uspace_window_buffer = frame_alloc(ONE_FRAME, FRAME_KA); |
} else { |
uintptr_t uw_buf = (uintptr_t) t->arch.uspace_window_buffer; |
75,7 → 76,7 |
* belonging to a killed thread. |
*/ |
t->arch.uspace_window_buffer = (uint8_t *) ALIGN_DOWN(uw_buf, |
UWB_ASIZE); |
PAGE_SIZE); |
} |
} |
/branches/dd/kernel/arch/sparc64/src/cpu/cpu.c |
---|
32,46 → 32,12 |
/** @file |
*/ |
#include <arch/cpu_family.h> |
#include <cpu.h> |
#include <arch.h> |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/drivers/tick.h> |
#include <print.h> |
#include <arch/cpu_node.h> |
/** |
* Finds out the clock frequency of the current CPU. |
* |
* @param node node representing the current CPU in the OFW tree |
* @return clock frequency if "node" is the current CPU and no error |
* occurs, -1 if "node" is not the current CPU or on error |
*/ |
static int find_cpu_frequency(ofw_tree_node_t *node) |
{ |
ofw_tree_property_t *prop; |
uint32_t mid; |
/* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ |
prop = ofw_tree_getprop(node, "upa-portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "portid"); |
if ((!prop) || (!prop->value)) |
prop = ofw_tree_getprop(node, "cpuid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, "clock-frequency"); |
if (prop && prop->value) { |
return *((uint32_t *) prop->value); |
} |
} |
} |
return -1; |
} |
/** Perform sparc64 specific initialization of the processor structure for the |
* current processor. |
*/ |
78,37 → 44,34 |
void cpu_arch_init(void) |
{ |
ofw_tree_node_t *node; |
uint32_t mid; |
uint32_t clock_frequency = 0; |
upa_config_t upa_config; |
CPU->arch.mid = read_mid(); |
upa_config.value = upa_config_read(); |
CPU->arch.mid = upa_config.mid; |
/* |
* Detect processor frequency. |
*/ |
if (is_us() || is_us_iii()) { |
node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); |
while (node) { |
int f = find_cpu_frequency(node); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
node = ofw_tree_find_child_by_device_type(ofw_tree_lookup("/"), "cpu"); |
while (node) { |
ofw_tree_property_t *prop; |
prop = ofw_tree_getprop(node, "upa-portid"); |
if (prop && prop->value) { |
mid = *((uint32_t *) prop->value); |
if (mid == CPU->arch.mid) { |
prop = ofw_tree_getprop(node, |
"clock-frequency"); |
if (prop && prop->value) |
clock_frequency = *((uint32_t *) |
prop->value); |
} |
} |
} else if (is_us_iv()) { |
node = ofw_tree_find_child(cpus_parent(), "cmp"); |
while (node) { |
int f; |
f = find_cpu_frequency( |
ofw_tree_find_child(node, "cpu@0")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
f = find_cpu_frequency( |
ofw_tree_find_child(node, "cpu@1")); |
if (f != -1) |
clock_frequency = (uint32_t) f; |
node = ofw_tree_find_peer_by_name(node, "cmp"); |
} |
node = ofw_tree_find_peer_by_device_type(node, "cpu"); |
} |
CPU->arch.clock_frequency = clock_frequency; |
tick_init(); |
} |
161,15 → 124,6 |
case IMPL_ULTRASPARCIII: |
impl = "UltraSPARC III"; |
break; |
case IMPL_ULTRASPARCIII_PLUS: |
impl = "UltraSPARC III+"; |
break; |
case IMPL_ULTRASPARCIII_I: |
impl = "UltraSPARC IIIi"; |
break; |
case IMPL_ULTRASPARCIV: |
impl = "UltraSPARC IV"; |
break; |
case IMPL_ULTRASPARCIV_PLUS: |
impl = "UltraSPARC IV+"; |
break; |
181,7 → 135,7 |
break; |
} |
printf("cpu%d: manuf=%s, impl=%s, mask=%d (%d MHz)\n", m->id, manuf, |
printf("cpu%d: manuf=%s, impl=%s, mask=%d (%dMHz)\n", m->id, manuf, |
impl, m->arch.ver.mask, m->arch.clock_frequency / 1000000); |
} |
/branches/dd/kernel/arch/sparc64/src/asm.S |
---|
41,7 → 41,6 |
*/ |
.global memcpy |
memcpy: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
60,7 → 59,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
94,7 → 93,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
/* |
* Almost the same as memcpy() except the loads are from userspace. |
101,7 → 100,6 |
*/ |
.global memcpy_from_uspace |
memcpy_from_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
120,7 → 118,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
154,7 → 152,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
/* |
* Almost the same as memcpy() except the stores are to userspace. |
161,7 → 159,6 |
*/ |
.global memcpy_to_uspace |
memcpy_to_uspace: |
mov %o0, %o3 ! save dst |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
180,7 → 177,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
214,7 → 211,7 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
277,8 → 274,6 |
wrpr %g0, 0, %cleanwin ! avoid information leak |
mov %i2, %o0 ! uarg |
xor %o1, %o1, %o1 ! %o1 is defined to hold pcb_ptr |
! set it to 0 |
clr %i2 |
clr %i3 |
/branches/dd/kernel/arch/sparc64/src/sparc64.c |
---|
47,11 → 47,10 |
#include <genarch/ofw/ofw_tree.h> |
#include <userspace.h> |
#include <ddi/irq.h> |
#include <string.h> |
bootinfo_t bootinfo; |
/** Perform sparc64-specific initialization before main_bsp() is called. */ |
/** Perform sparc64 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Copy init task info. */ |
62,8 → 61,6 |
for (i = 0; i < bootinfo.taskmap.count; i++) { |
init.tasks[i].addr = (uintptr_t) bootinfo.taskmap.tasks[i].addr; |
init.tasks[i].size = bootinfo.taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo.taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
/* Copy boot allocations info. */ |
89,6 → 86,8 |
* But we only create 128 buckets. |
*/ |
irq_init(1 << 11, 128); |
standalone_sparc64_console_init(); |
} |
} |
102,16 → 101,16 |
void arch_post_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
standalone_sparc64_console_init(); |
static thread_t *t = NULL; |
/* Create thread that polls keyboard. |
* XXX: this is only used by sgcn now |
*/ |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", |
true); |
if (!t) { |
/* |
* Create thread that polls keyboard. |
*/ |
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("Cannot create kkbdpoll."); |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
} |
} |
162,19 → 161,5 |
while (1); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/sparc64/src/ddi/ddi.c |
---|
41,7 → 41,7 |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Starting I/O space address. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
/branches/dd/kernel/arch/sparc64/src/console.c |
---|
38,7 → 38,12 |
#include <arch/drivers/scr.h> |
#include <arch/drivers/kbd.h> |
#include <arch/drivers/sgcn.h> |
#ifdef CONFIG_Z8530 |
#include <genarch/kbd/z8530.h> |
#endif |
#ifdef CONFIG_NS16550 |
#include <genarch/kbd/ns16550.h> |
#endif |
#include <console/chardev.h> |
#include <console/console.h> |
49,81 → 54,47 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch.h> |
#include <panic.h> |
#include <string.h> |
#include <print.h> |
#define KEYBOARD_POLL_PAUSE 50000 /* 50ms */ |
/** |
* Initialize kernel console to use framebuffer and keyboard directly. |
* Called on UltraSPARC machines with standard keyboard and framebuffer. |
* |
* @param aliases the "/aliases" OBP node |
*/ |
static void standard_console_init(ofw_tree_node_t *aliases) |
/** Initialize kernel console to use framebuffer and keyboard directly. */ |
void standalone_sparc64_console_init(void) |
{ |
#ifdef CONFIG_FB |
stdin = NULL; |
ofw_tree_node_t *aliases; |
ofw_tree_property_t *prop; |
ofw_tree_node_t *screen; |
ofw_tree_node_t *keyboard; |
aliases = ofw_tree_lookup("/aliases"); |
if (!aliases) |
panic("Can't find /aliases.\n"); |
prop = ofw_tree_getprop(aliases, "screen"); |
if (!prop) |
panic("Cannot find property 'screen'."); |
panic("Can't find property \"screen\".\n"); |
if (!prop->value) |
panic("Cannot find screen alias."); |
panic("Can't find screen alias.\n"); |
screen = ofw_tree_lookup(prop->value); |
if (!screen) |
panic("Cannot find %s.", prop->value); |
panic("Can't find %s\n", prop->value); |
scr_init(screen); |
prop = ofw_tree_getprop(aliases, "keyboard"); |
if (!prop) |
panic("Cannot find property 'keyboard'."); |
panic("Can't find property \"keyboard\".\n"); |
if (!prop->value) |
panic("Cannot find keyboard alias."); |
panic("Can't find keyboard alias.\n"); |
keyboard = ofw_tree_lookup(prop->value); |
if (!keyboard) |
panic("Cannot find %s.", prop->value); |
panic("Can't find %s\n", prop->value); |
kbd_init(keyboard); |
#else |
panic("Standard console requires FB, " |
"but the kernel is not compiled with FB support."); |
#endif |
} |
/** Initilize I/O on the Serengeti machine. */ |
static void serengeti_init(void) |
{ |
sgcn_init(); |
} |
/** |
* Initialize input/output. Auto-detects the type of machine |
* and calls the appropriate I/O init routine. |
*/ |
void standalone_sparc64_console_init(void) |
{ |
ofw_tree_node_t *aliases; |
ofw_tree_property_t *prop; |
aliases = ofw_tree_lookup("/aliases"); |
if (!aliases) |
panic("Cannot find '/aliases'."); |
/* "def-cn" = "default console" */ |
prop = ofw_tree_getprop(aliases, "def-cn"); |
if ((!prop) || (!prop->value) || (strcmp(prop->value, "/sgcn") != 0)) { |
standard_console_init(aliases); |
} else { |
serengeti_init(); |
} |
} |
/** Kernel thread for polling keyboard. |
* |
* @param arg Ignored. |
132,13 → 103,19 |
{ |
thread_detach(THREAD); |
if (kbd_type != KBD_SGCN) |
#ifdef CONFIG_Z8530 |
if (kbd_type == KBD_Z8530) { |
/* |
* The z8530 driver is interrupt-driven. |
*/ |
return; |
} |
#endif |
while (1) { |
#ifdef CONFIG_SGCN |
if (kbd_type == KBD_SGCN) |
sgcn_poll(); |
#ifdef CONFIG_NS16550 |
if (kbd_type == KBD_NS16550) |
ns16550_poll(); |
#endif |
thread_usleep(KEYBOARD_POLL_PAUSE); |
} |
149,15 → 126,17 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
scr_redraw(); |
#endif |
switch (kbd_type) { |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
sgcn_grab(); |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_grab(); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_grab(); |
break; |
#endif |
default: |
break; |
} |
169,11 → 148,16 |
void arch_release_console(void) |
{ |
switch (kbd_type) { |
#ifdef CONFIG_SGCN |
case KBD_SGCN: |
sgcn_release(); |
#ifdef CONFIG_Z8530 |
case KBD_Z8530: |
z8530_release(); |
break; |
#endif |
#ifdef CONFIG_NS16550 |
case KBD_NS16550: |
ns16550_release(); |
break; |
#endif |
default: |
break; |
} |
/branches/dd/kernel/arch/sparc64/src/start.S |
---|
27,7 → 27,6 |
# |
#include <arch/arch.h> |
#include <arch/cpu.h> |
#include <arch/regdef.h> |
#include <arch/boot/boot.h> |
#include <arch/stack.h> |
48,16 → 47,6 |
#define BSP_FLAG 1 |
/* |
* 2^PHYSMEM_ADDR_SIZE is the size of the physical address space on |
* a given processor. |
*/ |
#if defined (US) |
#define PHYSMEM_ADDR_SIZE 41 |
#elif defined (US3) |
#define PHYSMEM_ADDR_SIZE 43 |
#endif |
/* |
* Here is where the kernel is passed control from the boot loader. |
* |
* The registers are expected to be in this state: |
78,13 → 67,11 |
and %o0, %l0, %l7 ! l7 <= bootstrap processor? |
andn %o0, %l0, %l6 ! l6 <= start of physical memory |
! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base. |
! Get bits 40:13 of physmem_base. |
srlx %l6, 13, %l5 |
sllx %l5, 13 + (63 - 40), %l5 |
srlx %l5, 63 - 40, %l5 ! l5 <= physmem_base[40:13] |
! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13] |
sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5 |
srlx %l5, 63 - (PHYSMEM_ADDR_SIZE - 1), %l5 |
/* |
* Setup basic runtime environment. |
*/ |
96,8 → 83,6 |
! consistent |
wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window |
! traps for kernel |
wrpr %g0, 0, %wstate ! use default spill/fill trap |
wrpr %g0, 0, %tl ! TL = 0, primary context |
! register is used |
259,8 → 244,7 |
/* |
* Precompute kernel 8K TLB data template. |
* %l5 contains starting physical address |
* bits [(PHYSMEM_ADDR_SIZE - 1):13] |
* %l5 contains starting physical address bits [40:13] |
*/ |
sethi %hi(kernel_8k_tlb_data_template), %l4 |
ldx [%l4 + %lo(kernel_8k_tlb_data_template)], %l3 |
298,32 → 282,15 |
nop |
1: |
#ifdef CONFIG_SMP |
/* |
* Determine the width of the MID and save its mask to %g3. The width |
* is |
* * 5 for US and US-IIIi, |
* * 10 for US3 except US-IIIi. |
*/ |
#if defined(US) |
mov 0x1f, %g3 |
#elif defined(US3) |
mov 0x3ff, %g3 |
rdpr %ver, %g2 |
sllx %g2, 16, %g2 |
srlx %g2, 48, %g2 |
cmp %g2, IMPL_ULTRASPARCIII_I |
move %xcc, 0x1f, %g3 |
#endif |
/* |
* Read MID from the processor. |
*/ |
ldxa [%g0] ASI_ICBUS_CONFIG, %g1 |
srlx %g1, ICBUS_CONFIG_MID_SHIFT, %g1 |
and %g1, %g3, %g1 |
1: |
ldxa [%g0] ASI_UPA_CONFIG, %g1 |
srlx %g1, UPA_CONFIG_MID_SHIFT, %g1 |
and %g1, UPA_CONFIG_MID_MASK, %g1 |
#ifdef CONFIG_SMP |
/* |
* Active loop for APs until the BSP picks them up. A processor cannot |
* leave the loop until the global variable 'waking_up_mid' equals its |
/branches/dd/kernel/arch/sparc64/Makefile.inc |
---|
33,7 → 33,7 |
BFD_ARCH = sparc |
BFD = binary |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64 |
TOOLCHAIN_DIR = /usr/local/sparc64 |
GCC_CFLAGS += -m64 -mcpu=ultrasparc |
SUNCC_CFLAGS += -m64 -xarch=sparc -xregs=appl,no%float |
42,59 → 42,80 |
DEFS += -D__64_BITS__ |
ifeq ($(PROCESSOR),us) |
DEFS += -DUS |
endif |
## Own configuration directives |
# |
ifeq ($(PROCESSOR),us3) |
DEFS += -DUS3 |
## Compile with page hash table support. |
# |
CONFIG_PAGE_HT = y |
DEFS += -DCONFIG_PAGE_HT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for framebuffer. |
# |
CONFIG_FB = y |
## Compile with support for Sun keyboard. |
# |
CONFIG_SUN_KBD = y |
## Compile with support for OpenFirmware device tree. |
# |
CONFIG_OFW_TREE = y |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/cache.S \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/sparc64.c \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/trap/mmu.S \ |
arch/$(KARCH)/src/trap/trap_table.S \ |
arch/$(KARCH)/src/trap/trap.c \ |
arch/$(KARCH)/src/trap/exception.c \ |
arch/$(KARCH)/src/trap/interrupt.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/tick.c \ |
arch/$(KARCH)/src/drivers/kbd.c \ |
arch/$(KARCH)/src/drivers/sgcn.c \ |
arch/$(KARCH)/src/drivers/pci.c |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/cache.S \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/sparc64.c \ |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/trap/mmu.S \ |
arch/$(ARCH)/src/trap/trap_table.S \ |
arch/$(ARCH)/src/trap/trap.c \ |
arch/$(ARCH)/src/trap/exception.c \ |
arch/$(ARCH)/src/trap/interrupt.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/tick.c \ |
arch/$(ARCH)/src/drivers/kbd.c \ |
arch/$(ARCH)/src/drivers/scr.c \ |
arch/$(ARCH)/src/drivers/pci.c |
ifeq ($(CONFIG_FB),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/drivers/scr.c |
endif |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/smp/smp.c |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/smp/smp.c |
endif |
ifeq ($(CONFIG_TSB),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/mm/tsb.c |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/mm/tsb.c |
endif |
ifdef CONFIG_Z8530 |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/drivers/fhc.c |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/drivers/fhc.c |
endif |
/branches/dd/kernel/arch/sparc64/_link.ld.in |
---|
1,8 → 1,8 |
/** SPARC64 linker script |
* |
* It is ELF format, but its only section looks like this: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* |
*/ |
11,7 → 11,7 |
ENTRY(kernel_image_start) |
SECTIONS { |
.image VMA: AT (LMA) { |
.image VMA: AT (LMA) { |
ktext_start = .; |
*(K_TEXT_START) |
*(.text); |
21,23 → 21,23 |
*(K_DATA_START) |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
. = ALIGN(8); |
hardcoded_ktext_size = .; |
QUAD(ktext_end - ktext_start); |
QUAD(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
QUAD(kdata_end - kdata_start); |
hardcoded_load_address = .; |
QUAD(VMA); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
*(symtab.*); /* Symbol table, must be LAST symbol!*/ |
kdata_end = .; |
} |
44,5 → 44,5 |
/DISCARD/ : { |
*(*); |
} |
} |
/branches/dd/kernel/arch/ia64/include/asm.h |
---|
36,72 → 36,29 |
#define KERN_ia64_ASM_H_ |
#include <config.h> |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/register.h> |
#define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
static inline void outb(uint64_t port,uint8_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))) = v; |
*((uint8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
static inline uint8_t inb(uint64_t port) |
{ |
uintptr_t prt = (uintptr_t) port; |
*((uint32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))) = v; |
asm volatile ("mf\n" ::: "memory"); |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((uint8_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
return *((char *)(IA64_IOSPACE_ADDRESS + ( (port & 0xfff) | ( (port >> 2) << 12 )))); |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((uint16_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uintptr_t prt = (uintptr_t) port; |
asm volatile ("mf\n" ::: "memory"); |
return *((uint32_t *)(IA64_IOSPACE_ADDRESS + |
((prt & 0xfff) | ((prt >> 2) << 12)))); |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
112,14 → 69,9 |
{ |
uint64_t v; |
//I'm not sure why but this code bad inlines in scheduler, |
//so THE shifts about 16B and causes kernel panic |
//asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//return v; |
asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
//this code have the same meaning but inlines well |
asm volatile ("mov %0 = r12" : "=r" (v) ); |
return v & (~(STACK_SIZE-1)); |
return v; |
} |
/** Return Processor State Register. |
171,16 → 123,6 |
return v; |
} |
static inline uint64_t cr64_read(void) |
{ |
uint64_t v; |
asm volatile ("mov %0 = cr64\n" : "=r" (v)); |
return v; |
} |
/** Write ITC (Interval Timer Counter) register. |
* |
* @param v New counter value. |
355,8 → 297,7 |
extern void cpu_sleep(void); |
extern void asm_delay_loop(uint32_t t); |
extern void switch_to_userspace(uintptr_t, uintptr_t, uintptr_t, uintptr_t, |
uint64_t, uint64_t); |
extern void switch_to_userspace(uintptr_t entry, uintptr_t sp, uintptr_t bsp, uintptr_t uspace_uarg, uint64_t ipsr, uint64_t rsc); |
#endif |
/branches/dd/kernel/arch/ia64/include/mm/page.h |
---|
41,30 → 41,15 |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
/** Bit width of the TLB-locked portion of kernel address space. */ |
#define KERNEL_PAGE_WIDTH 28 /* 256M */ |
#define IO_PAGE_WIDTH 26 /* 64M */ |
#define FW_PAGE_WIDTH 28 /* 256M */ |
#define USPACE_IO_PAGE_WIDTH 12 /* 4K */ |
/* |
* Statically mapped IO spaces - offsets to 0xe...00 of virtual addresses |
* because of "minimal virtual bits implemented is 51" it is possible to |
* have values up to 0x0007000000000000 |
*/ |
/* Firmware area (bellow 4GB in phys mem) */ |
#define FW_OFFSET 0x00000000F0000000 |
/* Legacy IO space */ |
#define IO_OFFSET 0x0001000000000000 |
/* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */ |
#define VIO_OFFSET 0x0002000000000000 |
#define PPN_SHIFT 12 |
#define VRN_SHIFT 61 |
79,8 → 64,8 |
#define REGION_REGISTERS 8 |
#define KA2PA(x) ((uintptr_t) (x - (VRN_KERNEL << VRN_SHIFT))) |
#define PA2KA(x) ((uintptr_t) (x + (VRN_KERNEL << VRN_SHIFT))) |
#define KA2PA(x) ((uintptr_t) (x-(VRN_KERNEL<<VRN_SHIFT))) |
#define PA2KA(x) ((uintptr_t) (x+(VRN_KERNEL<<VRN_SHIFT))) |
#define VHPT_WIDTH 20 /* 1M */ |
#define VHPT_SIZE (1 << VHPT_WIDTH) |
/branches/dd/kernel/arch/ia64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
35,16 → 35,12 |
#ifndef KERN_ia64_FRAME_H_ |
#define KERN_ia64_FRAME_H_ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <arch/types.h> |
extern uintptr_t last_frame; |
extern void frame_arch_init(void); |
#define physmem_print() |
/branches/dd/kernel/arch/ia64/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_ia64_TLB_H_ |
#define KERN_ia64_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#include <arch/mm/page.h> |
#include <arch/mm/asid.h> |
#include <arch/interrupt.h> |
43,8 → 46,8 |
/** Data and instruction Translation Register indices. */ |
#define DTR_KERNEL 0 |
#define ITR_KERNEL 0 |
#define DTR_KSTACK1 4 |
#define DTR_KSTACK2 5 |
#define DTR_KSTACK1 1 |
#define DTR_KSTACK2 2 |
/** Portion of TLB insertion format data structure. */ |
union tlb_entry { |
/branches/dd/kernel/arch/ia64/include/mm/vhpt.h |
---|
44,8 → 44,8 |
{ |
vhpt_entry_t ventry; |
ventry.word[0] = tentry.word[0]; |
ventry.word[1] = tentry.word[1]; |
ventry.word[0]=tentry.word[0]; |
ventry.word[1]=tentry.word[1]; |
return ventry; |
} |
/branches/dd/kernel/arch/ia64/include/drivers/kbd.h |
---|
File deleted |
/branches/dd/kernel/arch/ia64/include/drivers/ega.h |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* 2007 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia64_EGA_H |
#define KERN_ia64_EGA_H |
#define VIDEORAM (0xe0020000000B8000LL) |
#define ROW 80 |
#define ROWS 25 |
#define SCREEN (ROW * ROWS) |
extern void ega_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/include/drivers/i8042.h |
---|
0,0 → 1,71 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements ia32 specific access to i8042 registers. |
*/ |
#ifndef KERN_ia64_I8042_H_ |
#define KERN_ia64_I8042_H_ |
#include <arch/asm.h> |
#include <arch/types.h> |
#define i8042_DATA 0x60 |
#define i8042_STATUS 0x64 |
static inline void i8042_data_write(uint8_t data) |
{ |
outb(i8042_DATA, data); |
} |
static inline uint8_t i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline uint8_t i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(uint8_t command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/include/drivers/it.h |
---|
41,7 → 41,7 |
* from firmware. |
* |
*/ |
#define IT_DELTA it_delta |
#define IT_DELTA 100000 |
extern void it_init(void); |
/branches/dd/kernel/arch/ia64/include/interrupt.h |
---|
50,13 → 50,10 |
#define IVT_FIRST 0 |
/** External Interrupt vectors. */ |
#define VECTOR_TLB_SHOOTDOWN_IPI 0xf0 |
#define INTERRUPT_TIMER 255 |
#define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) |
#define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) |
#define IRQ_KBD 241 |
#define IRQ_MOUSE 252 |
#define INTERRUPT_SPURIOUS 15 |
#define LEGACY_INTERRUPT_BASE 0x20 |
/** General Exception codes. */ |
#define GE_ILLEGALOP 0 |
117,7 → 114,7 |
/* |
* The following variables are defined only for break_instruction |
* handler. |
* handler. |
*/ |
uint64_t in0; |
uint64_t in1; |
153,8 → 150,6 |
extern void external_interrupt(uint64_t vector, istate_t *istate); |
extern void disabled_fp_register(uint64_t vector, istate_t *istate); |
extern void trap_virtual_enable_irqs(uint16_t irqmask); |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/bootinfo.h |
---|
29,23 → 29,13 |
#ifndef KERN_ia64_BOOTINFO_H_ |
#define KERN_ia64_BOOTINFO_H_ |
#define BOOTINFO_ADDRESS 0x4401000 |
#define CONFIG_INIT_TASKS 32 |
#define MEMMAP_ITEMS 128 |
#define EFI_MEMMAP_FREE_MEM 0 |
#define EFI_MEMMAP_IO 1 |
#define EFI_MEMMAP_IO_PORTS 2 |
/** Size of buffer for storing task name in binit_task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
typedef struct { |
void *addr; |
unsigned long size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} binit_task_t; |
typedef struct { |
53,24 → 43,9 |
binit_task_t tasks[CONFIG_INIT_TASKS]; |
} binit_t; |
typedef struct { |
unsigned int type; |
unsigned long base; |
unsigned long size; |
}efi_memmap_item_t; |
typedef struct { |
binit_t taskmap; |
efi_memmap_item_t memmap[MEMMAP_ITEMS]; |
unsigned int memmap_items; |
unsigned long * sapic; |
unsigned long sys_freq; |
unsigned long freq_scale; |
unsigned int wakeup_intno; |
int hello_configured; |
} bootinfo_t; |
extern bootinfo_t *bootinfo; |
/branches/dd/kernel/arch/ia64/include/types.h |
---|
35,6 → 35,10 |
#ifndef KERN_ia64_TYPES_H_ |
#define KERN_ia64_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
65,34 → 69,14 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
unative_t fnc; |
unative_t gp; |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
#define PRIp "lx" /**< Format for uintptr_t. */ |
#define PRIs "lu" /**< Format for size_t. */ |
#define PRIc "lu" /**< Format for count_t. */ |
#define PRIi "lu" /**< Format for index_t. */ |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "d" /**< Format for int32_t. */ |
#define PRId64 "ld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
#define PRIu8 "u" /**< Format for uint8_t. */ |
#define PRIu16 "u" /**< Format for uint16_t. */ |
#define PRIu32 "u" /**< Format for uint32_t. */ |
#define PRIu64 "lu" /**< Format for uint64_t. */ |
#define PRIun "u" /**< Format for unative_t. */ |
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ |
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ |
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ |
#define PRIx64 "lx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/fpu_context.h |
---|
35,6 → 35,7 |
#ifndef KERN_ia64_FPU_CONTEXT_H_ |
#define KERN_ia64_FPU_CONTEXT_H_ |
#define ARCH_HAS_FPU 1 |
#define FPU_CONTEXT_ALIGN 16 |
#include <arch/types.h> |
/branches/dd/kernel/arch/ia64/include/cpu.h |
---|
38,7 → 38,6 |
#include <arch/types.h> |
#include <arch/register.h> |
#include <arch/asm.h> |
#include <arch/bootinfo.h> |
#define FAMILY_ITANIUM 0x7 |
#define FAMILY_ITANIUM2 0x1f |
64,32 → 63,6 |
return v; |
} |
#define CR64_ID_SHIFT 24 |
#define CR64_ID_MASK 0xff000000 |
#define CR64_EID_SHIFT 16 |
#define CR64_EID_MASK 0xff0000 |
static inline int ia64_get_cpu_id(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_ID_MASK)&cr64)>>CR64_ID_SHIFT; |
} |
static inline int ia64_get_cpu_eid(void) |
{ |
uint64_t cr64=cr64_read(); |
return ((CR64_EID_MASK)&cr64)>>CR64_EID_SHIFT; |
} |
static inline void ipi_send_ipi(int id, int eid, int intno) |
{ |
(bootinfo->sapic)[2 * (id * 256 + eid)] = intno; |
srlz_d(); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/atomic.h |
---|
37,65 → 37,29 |
/** Atomic addition. |
* |
* @param val Atomic value. |
* @param imm Value to add. |
* @param val Atomic value. |
* @param imm Value to add. |
* |
* @return Value before addition. |
* @return Value before addition. |
*/ |
static inline long atomic_add(atomic_t *val, int imm) |
{ |
long v; |
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), |
"+m" (val->count) : "i" (imm)); |
asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm)); |
return v; |
} |
static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); } |
static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); } |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movl %0 = 0x01;;\n" |
"xchg8 %0 = %1, %0;;\n" |
: "=r" (v), "+m" (val->count) |
); |
return v; |
} |
static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; } |
static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; } |
static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); } |
static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); } |
static inline void atomic_inc(atomic_t *val) |
{ |
atomic_add(val, 1); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
atomic_add(val, -1); |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
return atomic_add(val, 1) + 1; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
return atomic_add(val, -1) - 1; |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
return atomic_add(val, 1); |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
return atomic_add(val, -1); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/barrier.h |
---|
45,33 → 45,9 |
#define read_barrier() memory_barrier() |
#define write_barrier() memory_barrier() |
#define srlz_i() \ |
asm volatile (";; srlz.i ;;\n" ::: "memory") |
#define srlz_d() \ |
asm volatile (";; srlz.d\n" ::: "memory") |
#define srlz_i() asm volatile (";; srlz.i ;;\n" ::: "memory") |
#define srlz_d() asm volatile (";; srlz.d\n" ::: "memory") |
#define fc_i(a) \ |
asm volatile ("fc.i %0\n" :: "r" ((a)) : "memory") |
#define sync_i() \ |
asm volatile (";; sync.i\n" ::: "memory") |
#define smc_coherence(a) \ |
{ \ |
fc_i((a)); \ |
sync_i(); \ |
srlz_i(); \ |
} |
#define FC_INVAL_MIN 32 |
#define smc_coherence_block(a, l) \ |
{ \ |
unsigned long i; \ |
for (i = 0; i < (l); i += FC_INVAL_MIN) \ |
fc_i((void *)(a) + i); \ |
sync_i(); \ |
srlz_i(); \ |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/branches/dd/kernel/arch/ia64/include/arch.h |
---|
39,8 → 39,6 |
#include <arch/ski/ski.h> |
extern void arch_pre_main(void); |
#endif |
/** @} |
/branches/dd/kernel/arch/ia64/include/proc/task.h |
---|
31,19 → 31,14 |
*/ |
/** @file |
*/ |
#include <proc/task.h> |
#ifndef KERN_ia64_TASK_H_ |
#define KERN_ia64_TASK_H_ |
#include <adt/bitmap.h> |
typedef struct { |
bitmap_t *iomap; |
} task_arch_t; |
#define task_create_arch(t) { (t)->arch.iomap = NULL; } |
#define task_create_arch(t) |
#define task_destroy_arch(t) |
#endif |
/branches/dd/kernel/arch/ia64/include/register.h |
---|
40,11 → 40,11 |
#define PSR_I_MASK 0x4000 |
#define PSR_PK_MASK 0x8000 |
#define PSR_DT_MASK (1 << 17) |
#define PSR_RT_MASK (1 << 27) |
#define PSR_DT_MASK (1<<17) |
#define PSR_RT_MASK (1<<27) |
#define PSR_DFL_MASK (1 << 18) |
#define PSR_DFH_MASK (1 << 19) |
#define PSR_DFL_MASK (1<<18) |
#define PSR_DFH_MASK (1<<19) |
#define PSR_IT_MASK 0x0000001000000000 |
/branches/dd/kernel/arch/ia64/include/debug.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* Copyright (c) 2005 |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
/branches/dd/kernel/arch/ia64/src/smp/smp.c |
---|
File deleted |
/branches/dd/kernel/arch/ia64/src/ia64.c |
---|
51,99 → 51,64 |
#include <syscall/syscall.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <arch/drivers/ega.h> |
#include <arch/bootinfo.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/srln/srln.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/drivers/ns16550/ns16550.h> |
#include <arch/drivers/kbd.h> |
#include <smp/smp.h> |
#include <smp/ipi.h> |
#include <arch/atomic.h> |
#include <panic.h> |
#include <print.h> |
#include <sysinfo/sysinfo.h> |
#include <string.h> |
#include <genarch/kbd/i8042.h> |
/* NS16550 as a COM 1 */ |
#define NS16550_IRQ (4 + LEGACY_INTERRUPT_BASE) |
bootinfo_t *bootinfo; |
static uint64_t iosapic_base = 0xfec00000; |
/** Performs ia64-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
/* Setup usermode init tasks. */ |
//#ifdef I460GX |
unsigned int i; |
init.cnt = bootinfo->taskmap.count; |
for (i = 0; i < init.cnt; i++) { |
init.tasks[i].addr = |
((unsigned long) bootinfo->taskmap.tasks[i].addr) | |
VRN_MASK; |
init.tasks[i].addr = ((unsigned long) bootinfo->taskmap.tasks[i].addr) | VRN_MASK; |
init.tasks[i].size = bootinfo->taskmap.tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->taskmap.tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
/* |
#else |
init.cnt = 8; |
init.tasks[0].addr = INIT0_ADDRESS; |
init.tasks[0].size = INIT0_SIZE; |
init.tasks[1].addr = INIT0_ADDRESS + 0x400000; |
init.tasks[1].size = INIT0_SIZE; |
init.tasks[2].addr = INIT0_ADDRESS + 0x800000; |
init.tasks[2].size = INIT0_SIZE; |
init.tasks[3].addr = INIT0_ADDRESS + 0xc00000; |
init.tasks[3].size = INIT0_SIZE; |
init.tasks[4].addr = INIT0_ADDRESS + 0x1000000; |
init.tasks[4].size = INIT0_SIZE; |
init.tasks[5].addr = INIT0_ADDRESS + 0x1400000; |
init.tasks[5].size = INIT0_SIZE; |
init.tasks[6].addr = INIT0_ADDRESS + 0x1800000; |
init.tasks[6].size = INIT0_SIZE; |
init.tasks[7].addr = INIT0_ADDRESS + 0x1c00000; |
init.tasks[7].size = INIT0_SIZE; |
#endif*/ |
} |
void arch_pre_mm_init(void) |
{ |
/* |
* Set Interruption Vector Address (i.e. location of interruption vector |
* table). |
*/ |
/* Set Interruption Vector Address (i.e. location of interruption vector table). */ |
iva_write((uintptr_t) &ivt); |
srlz_d(); |
} |
static void iosapic_init(void) |
{ |
uint64_t IOSAPIC = PA2KA((unative_t)(iosapic_base)) | FW_OFFSET; |
int i; |
int myid, myeid; |
myid = ia64_get_cpu_id(); |
myeid = ia64_get_cpu_eid(); |
for (i = 0; i < 16; i++) { |
if (i == 2) |
continue; /* Disable Cascade interrupt */ |
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x10))[0] = LEGACY_INTERRUPT_BASE + i; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x00))[0] = 0x10 + 2 * i + 1; |
srlz_d(); |
((uint32_t *)(IOSAPIC + 0x10))[0] = myid << (56 - 32) | |
myeid << (48 - 32); |
srlz_d(); |
} |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
iosapic_init(); |
irq_init(INR_COUNT, INR_COUNT); |
irq_init(INR_COUNT, INR_COUNT); |
#ifdef SKI |
ski_init_console(); |
#else |
ega_init(EGA_BASE, EGA_VIDEORAM); |
#endif |
} |
it_init(); |
ski_init_console(); |
#else |
ega_init(); |
#endif |
it_init(); |
} |
void arch_post_cpu_init(void) |
154,54 → 119,51 |
{ |
} |
#ifdef I460GX |
#define POLL_INTERVAL 50000 /* 50 ms */ |
/** Kernel thread for polling keyboard. */ |
static void i8042_kkbdpoll(void *arg) |
{ |
while (1) { |
i8042_poll(); |
thread_usleep(POLL_INTERVAL); |
} |
} |
#endif |
void arch_post_smp_init(void) |
{ |
/* |
* Create thread that polls keyboard. |
*/ |
if (config.cpu_active == 1) { |
/* |
* Create thread that polls keyboard. |
*/ |
#ifdef SKI |
thread_t *t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("Cannot create kkbdpoll."); |
thread_ready(t); |
thread_t *t; |
t = thread_create(kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
#endif |
#ifdef I460GX |
devno_t devno = device_assign_devno(); |
inr_t inr; |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
#ifdef CONFIG_NS16550 |
inr = NS16550_IRQ; |
srln_init(stdin); |
(void) ns16550_init((ns16550_t *)NS16550_BASE, devno, inr, NULL, NULL, |
&srlnin); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) NS16550_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) NS16550_BASE); |
#else |
inr = IRQ_KBD; |
kbrd_init(stdin); |
(void) i8042_init((i8042_t *)I8042_BASE, devno, inr, &kbrdin); |
trap_virtual_enable_irqs(1 << inr); |
sysinfo_set_item_val("kbd.type", NULL, KBD_LEGACY); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
thread_t *t; |
t = thread_create(i8042_kkbdpoll, NULL, TASK, 0, "kkbdpoll", true); |
if (!t) |
panic("cannot create kkbdpoll\n"); |
thread_ready(t); |
#endif |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
#endif |
sysinfo_set_item_val("ia64_iospace", NULL, true); |
sysinfo_set_item_val("ia64_iospace.address", NULL, true); |
sysinfo_set_item_val("ia64_iospace.address.virtual", NULL, IO_OFFSET); |
} |
} |
/** Enter userspace and never return. */ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
210,25 → 172,26 |
psr.value = psr_read(); |
psr.cpl = PL_USER; |
psr.i = true; /* start with interrupts enabled */ |
psr.i = true; /* start with interrupts enabled */ |
psr.ic = true; |
psr.ri = 0; /* start with instruction #0 */ |
psr.bn = 1; /* start in bank 0 */ |
psr.ri = 0; /* start with instruction #0 */ |
psr.bn = 1; /* start in bank 0 */ |
asm volatile ("mov %0 = ar.rsc\n" : "=r" (rsc.value)); |
rsc.loadrs = 0; |
rsc.be = false; |
rsc.pl = PL_USER; |
rsc.mode = 3; /* eager mode */ |
rsc.mode = 3; /* eager mode */ |
switch_to_userspace((uintptr_t) kernel_uarg->uspace_entry, |
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE - |
ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
((uintptr_t) kernel_uarg->uspace_stack) + PAGE_SIZE, |
(uintptr_t) kernel_uarg->uspace_uarg, psr.value, rsc.value); |
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE-ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT), |
((uintptr_t) kernel_uarg->uspace_stack)+PAGE_SIZE, |
(uintptr_t) kernel_uarg->uspace_uarg, |
psr.value, rsc.value); |
while (1) |
while (1) { |
; |
} |
} |
/** Set thread-local-storage pointer. |
247,9 → 210,8 |
{ |
#ifdef SKI |
ski_kbd_grab(); |
#endif |
#endif |
} |
/** Return console to userspace |
* |
*/ |
262,27 → 224,9 |
void arch_reboot(void) |
{ |
pio_write_8((ioport8_t *)0x64, 0xfe); |
while (1) |
; |
// TODO |
while (1); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
fptr->fnc = (unative_t) addr; |
fptr->gp = ((unative_t *) caller)[1]; |
return (void *) fptr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/src/mm/tlb.c |
---|
92,7 → 92,7 |
/** Invalidate entries belonging to an address space. |
* |
* @param asid Address space identifier. |
* @param asid Address space identifier. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
131,45 → 131,59 |
uint64_t ps; |
switch (b) { |
case 0: /* cnt 1 - 3 */ |
case 0: /*cnt 1-3*/ |
ps = PAGE_WIDTH; |
break; |
case 1: /* cnt 4 - 15 */ |
ps = PAGE_WIDTH + 2; |
va &= ~((1 << ps) - 1); |
case 1: /*cnt 4-15*/ |
/*cnt=((cnt-1)/4)+1;*/ |
ps = PAGE_WIDTH+2; |
va &= ~((1<<ps)-1); |
break; |
case 2: /* cnt 16 - 63 */ |
ps = PAGE_WIDTH + 4; |
va &= ~((1 << ps) - 1); |
case 2: /*cnt 16-63*/ |
/*cnt=((cnt-1)/16)+1;*/ |
ps = PAGE_WIDTH+4; |
va &= ~((1<<ps)-1); |
break; |
case 3: /* cnt 64 - 255 */ |
ps = PAGE_WIDTH + 6; |
va &= ~((1 << ps) - 1); |
case 3: /*cnt 64-255*/ |
/*cnt=((cnt-1)/64)+1;*/ |
ps = PAGE_WIDTH+6; |
va &= ~((1<<ps)-1); |
break; |
case 4: /* cnt 256 - 1023 */ |
ps = PAGE_WIDTH + 8; |
va &= ~((1 << ps) - 1); |
case 4: /*cnt 256-1023*/ |
/*cnt=((cnt-1)/256)+1;*/ |
ps = PAGE_WIDTH+8; |
va &= ~((1<<ps)-1); |
break; |
case 5: /* cnt 1024 - 4095 */ |
ps = PAGE_WIDTH + 10; |
va &= ~((1 << ps) - 1); |
case 5: /*cnt 1024-4095*/ |
/*cnt=((cnt-1)/1024)+1;*/ |
ps = PAGE_WIDTH+10; |
va &= ~((1<<ps)-1); |
break; |
case 6: /* cnt 4096 - 16383 */ |
ps = PAGE_WIDTH + 12; |
va &= ~((1 << ps) - 1); |
case 6: /*cnt 4096-16383*/ |
/*cnt=((cnt-1)/4096)+1;*/ |
ps = PAGE_WIDTH+12; |
va &= ~((1<<ps)-1); |
break; |
case 7: /* cnt 16384 - 65535 */ |
case 8: /* cnt 65536 - (256K - 1) */ |
ps = PAGE_WIDTH + 14; |
va &= ~((1 << ps) - 1); |
case 7: /*cnt 16384-65535*/ |
case 8: /*cnt 65536-(256K-1)*/ |
/*cnt=((cnt-1)/16384)+1;*/ |
ps = PAGE_WIDTH+14; |
va &= ~((1<<ps)-1); |
break; |
default: |
ps = PAGE_WIDTH + 18; |
va &= ~((1 << ps) - 1); |
/*cnt=((cnt-1)/(16384*16))+1;*/ |
ps=PAGE_WIDTH+18; |
va&=~((1<<ps)-1); |
break; |
} |
for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps)) |
asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2)); |
/*cnt+=(page!=va);*/ |
for(; va<(page+cnt*(PAGE_SIZE)); va += (1<<ps)) { |
asm volatile ( |
"ptc.l %0,%1;;" |
: |
: "r" (va), "r" (ps<<2) |
); |
} |
srlz_d(); |
srlz_i(); |
182,10 → 196,9 |
/** Insert data into data translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
*/ |
void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) |
{ |
194,10 → 207,9 |
/** Insert data into instruction translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
*/ |
void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) |
{ |
206,12 → 218,10 |
/** Insert data into instruction or data translation cache. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param dtc If true, insert into data translation cache, use |
* instruction translation cache otherwise. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param dtc If true, insert into data translation cache, use instruction translation cache otherwise. |
*/ |
void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc) |
{ |
234,20 → 244,19 |
} |
asm volatile ( |
"mov r8 = psr;;\n" |
"mov r8=psr;;\n" |
"rsm %0;;\n" /* PSR_IC_MASK */ |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa = %1\n" /* va */ |
"mov cr.itir = %2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ |
"mov cr.ifa=%1\n" /* va */ |
"mov cr.itir=%2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ |
"(p6) itc.i %3;;\n" |
"(p7) itc.d %3;;\n" |
"mov psr.l = r8;;\n" |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), |
"r" (entry.word[0]), "r" (dtc) |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (dtc) |
: "p6", "p7", "r8" |
); |
260,14 → 269,12 |
/** Insert data into instruction translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param tr Translation register. |
*/ |
void |
itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
{ |
tr_mapping_insert(va, asid, entry, false, tr); |
} |
274,14 → 281,12 |
/** Insert data into data translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param tr Translation register. |
*/ |
void |
dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, index_t tr) |
{ |
tr_mapping_insert(va, asid, entry, true, tr); |
} |
288,17 → 293,13 |
/** Insert data into instruction or data translation register. |
* |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion |
* format. |
* @param dtr If true, insert into data translation register, use |
* instruction translation register otherwise. |
* @param tr Translation register. |
* @param va Virtual page address. |
* @param asid Address space identifier. |
* @param entry The rest of TLB entry as required by TLB insertion format. |
* @param dtr If true, insert into data translation register, use instruction translation register otherwise. |
* @param tr Translation register. |
*/ |
void |
tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, |
index_t tr) |
void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, index_t tr) |
{ |
region_register rr; |
bool restore_rr = false; |
319,20 → 320,19 |
} |
asm volatile ( |
"mov r8 = psr;;\n" |
"mov r8=psr;;\n" |
"rsm %0;;\n" /* PSR_IC_MASK */ |
"srlz.d;;\n" |
"srlz.i;;\n" |
"mov cr.ifa = %1\n" /* va */ |
"mov cr.itir = %2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */ |
"(p6) itr.i itr[%4] = %3;;\n" |
"(p7) itr.d dtr[%4] = %3;;\n" |
"mov psr.l = r8;;\n" |
"mov cr.ifa=%1\n" /* va */ |
"mov cr.itir=%2;;\n" /* entry.word[1] */ |
"cmp.eq p6,p7=%5,r0;;\n" /* decide between itr and dtr */ |
"(p6) itr.i itr[%4]=%3;;\n" |
"(p7) itr.d dtr[%4]=%3;;\n" |
"mov psr.l=r8;;\n" |
"srlz.d;;\n" |
: |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), |
"r" (entry.word[0]), "r" (tr), "r" (dtr) |
: "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), "r" (entry.word[0]), "r" (tr), "r" (dtr) |
: "p6", "p7", "r8" |
); |
345,15 → 345,12 |
/** Insert data into DTLB. |
* |
* @param page Virtual page address including VRN bits. |
* @param frame Physical frame address. |
* @param dtr If true, insert into data translation register, use data |
* translation cache otherwise. |
* @param tr Translation register if dtr is true, ignored otherwise. |
* @param page Virtual page address including VRN bits. |
* @param frame Physical frame address. |
* @param dtr If true, insert into data translation register, use data translation cache otherwise. |
* @param tr Translation register if dtr is true, ignored otherwise. |
*/ |
void |
dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, |
index_t tr) |
void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, index_t tr) |
{ |
tlb_entry_t entry; |
379,18 → 376,18 |
* |
* Purge DTR entries used by the kernel. |
* |
* @param page Virtual page address including VRN bits. |
* @param width Width of the purge in bits. |
* @param page Virtual page address including VRN bits. |
* @param width Width of the purge in bits. |
*/ |
void dtr_purge(uintptr_t page, count_t width) |
{ |
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2)); |
asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width<<2)); |
} |
/** Copy content of PTE into data translation cache. |
* |
* @param t PTE. |
* @param t PTE. |
*/ |
void dtc_pte_copy(pte_t *t) |
{ |
416,7 → 413,7 |
/** Copy content of PTE into instruction translation cache. |
* |
* @param t PTE. |
* @param t PTE. |
*/ |
void itc_pte_copy(pte_t *t) |
{ |
443,8 → 440,8 |
/** Instruction TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
472,77 → 469,16 |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
} |
} |
} |
static int is_io_page_accessible(int page) |
{ |
if (TASK->arch.iomap) |
return bitmap_get(TASK->arch.iomap, page); |
else |
return 0; |
} |
#define IO_FRAME_BASE 0xFFFFC000000 |
/** |
* There is special handling of memory mapped legacy io, because of 4KB sized |
* access for userspace. |
* |
* @param va Virtual address of page fault. |
* @param istate Structure with saved interruption state. |
* |
* @return One on success, zero on failure. |
*/ |
static int try_memmap_io_insertion(uintptr_t va, istate_t *istate) |
{ |
if ((va >= IO_OFFSET ) && (va < IO_OFFSET + (1 << IO_PAGE_WIDTH))) { |
if (TASK) { |
uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >> |
USPACE_IO_PAGE_WIDTH; |
if (is_io_page_accessible(io_page)) { |
uint64_t page, frame; |
page = IO_OFFSET + |
(1 << USPACE_IO_PAGE_WIDTH) * io_page; |
frame = IO_FRAME_BASE + |
(1 << USPACE_IO_PAGE_WIDTH) * io_page; |
tlb_entry_t entry; |
entry.word[0] = 0; |
entry.word[1] = 0; |
entry.p = true; /* present */ |
entry.ma = MA_UNCACHEABLE; |
entry.a = true; /* already accessed */ |
entry.d = true; /* already dirty */ |
entry.pl = PL_USER; |
entry.ar = AR_READ | AR_WRITE; |
entry.ppn = frame >> PPN_SHIFT; |
entry.ps = USPACE_IO_PAGE_WIDTH; |
dtc_mapping_insert(page, TASK->as->asid, entry); |
return 1; |
} else { |
fault_if_from_uspace(istate, |
"IO access fault at %p.", va); |
} |
} |
} |
return 0; |
} |
/** Data TLB fault handler for faults with VHPT turned off. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void alternate_data_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
575,17 → 511,13 |
dtc_pte_copy(t); |
page_table_unlock(AS, true); |
} else { |
page_table_unlock(AS, true); |
if (try_memmap_io_insertion(va, istate)) |
return; |
/* |
* Forward the page fault to the address space page fault |
* handler. |
* Forward the page fault to the address space page fault handler. |
*/ |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
} |
} |
} |
594,18 → 526,18 |
* |
* This fault should not occur. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void data_nested_tlb_fault(uint64_t vector, istate_t *istate) |
{ |
panic("%s.", __func__); |
panic("%s\n", __func__); |
} |
/** Data Dirty bit fault handler. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void data_dirty_bit_fault(uint64_t vector, istate_t *istate) |
{ |
630,9 → 562,10 |
dtc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate,"Page fault at %p.",va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->d = true; |
dtc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
640,8 → 573,8 |
/** Instruction access bit fault handler. |
* |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
* @param vector Interruption vector. |
* @param istate Structure with saved interruption state. |
*/ |
void instruction_access_bit_fault(uint64_t vector, istate_t *istate) |
{ |
666,9 → 599,10 |
itc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->a = true; |
itc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
702,9 → 636,10 |
dtc_pte_copy(t); |
} else { |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, |
istate->cr_iip); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d, iip=%p\n", __func__, va, rid, istate->cr_iip); |
t->a = true; |
itc_pte_copy(t); |
} |
} |
page_table_unlock(AS, true); |
743,19 → 678,11 |
} else { |
page_table_unlock(AS, true); |
if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault at %p.", va); |
panic("%s: va=%p, rid=%d.", __func__, va, rid); |
fault_if_from_uspace(istate,"Page fault at %p",va); |
panic("%s: va=%p, rid=%d\n", __func__, va, rid); |
} |
} |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
36,55 → 36,26 |
#include <mm/frame.h> |
#include <config.h> |
#include <panic.h> |
#include <arch/bootinfo.h> |
#include <align.h> |
#include <macros.h> |
#define KERNEL_RESERVED_AREA_BASE (0x4400000) |
#define KERNEL_RESERVED_AREA_SIZE (16 * 1024 * 1024) |
/* |
* This is Ski-specific and certainly not sufficient |
* for real ia64 systems that provide memory map. |
*/ |
#define MEMORY_SIZE (64 * 1024 * 1024) |
#define MEMORY_BASE (64 * 1024 * 1024) |
#define ROM_BASE 0xa0000 /* for simulators */ |
#define ROM_SIZE (384 * 1024) /* for simulators */ |
#define MIN_ZONE_SIZE (64 * 1024) |
#define MINCONF 1 |
uintptr_t last_frame = 0; |
#define ROM_BASE 0xa0000 //For ski |
#define ROM_SIZE (384 * 1024) //For ski |
void poke_char(int x,int y,char ch, char c); |
void frame_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
unsigned int i; |
for (i = 0; i < bootinfo->memmap_items; i++) { |
if (bootinfo->memmap[i].type == EFI_MEMMAP_FREE_MEM) { |
uint64_t base = bootinfo->memmap[i].base; |
uint64_t size = bootinfo->memmap[i].size; |
uint64_t abase = ALIGN_UP(base, FRAME_SIZE); |
if (size > FRAME_SIZE) |
size -= abase - base; |
if (size > MIN_ZONE_SIZE) { |
zone_create(abase >> FRAME_WIDTH, |
size >> FRAME_WIDTH, |
max(MINCONF, abase >> FRAME_WIDTH), |
0); |
} |
if (abase + size > last_frame) |
last_frame = abase + size; |
} |
} |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), |
SIZE2FRAMES(ROM_SIZE)); |
frame_mark_unavailable(ADDR2PFN(KERNEL_RESERVED_AREA_BASE), |
SIZE2FRAMES(KERNEL_RESERVED_AREA_SIZE)); |
} |
zone_create(MEMORY_BASE >> FRAME_WIDTH, SIZE2FRAMES(MEMORY_SIZE), (MEMORY_SIZE) >> FRAME_WIDTH, 0); |
/* |
* Blacklist ROM regions. |
*/ |
frame_mark_unavailable(ADDR2PFN(ROM_BASE), SIZE2FRAMES(ROM_SIZE)); |
} |
/** @} |
/branches/dd/kernel/arch/ia64/src/mm/as.c |
---|
68,7 → 68,7 |
continue; |
rr.word = rr_read(i); |
rr.map.ve = false; /* disable VHPT walker */ |
rr.map.ve = false; /* disable VHPT walker */ |
rr.map.rid = ASID2RID(as->asid, i); |
rr.map.ps = PAGE_WIDTH; |
rr_write(i, rr.word); |
/branches/dd/kernel/arch/ia64/src/mm/vhpt.c |
---|
41,8 → 41,7 |
uintptr_t vhpt_set_up(void) |
{ |
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, |
FRAME_KA | FRAME_ATOMIC); |
vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, FRAME_KA | FRAME_ATOMIC); |
if (!vhpt_base) |
panic("Kernel configured with VHPT but no memory for table."); |
vhpt_invalidate_all(); |
82,7 → 81,7 |
void vhpt_invalidate_all() |
{ |
memsetb(vhpt_base, 1 << VHPT_WIDTH, 0); |
memsetb((uintptr_t) vhpt_base, 1 << VHPT_WIDTH, 0); |
} |
void vhpt_invalidate_asid(asid_t asid) |
/branches/dd/kernel/arch/ia64/src/mm/page.c |
---|
27,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64mm |
/** @addtogroup ia64mm |
* @{ |
*/ |
/** @file |
47,7 → 47,6 |
#include <arch/asm.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <align.h> |
static void set_environment(void); |
63,9 → 62,9 |
void set_environment(void) |
{ |
region_register rr; |
pta_register pta; |
pta_register pta; |
int i; |
#ifdef CONFIG_VHPT |
#ifdef CONFIG_VHPT |
uintptr_t vhpt_base; |
#endif |
123,10 → 122,10 |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return VHPT entry address. |
* @return VHPT entry address. |
*/ |
vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid) |
{ |
167,11 → 166,10 |
* |
* Interrupts must be disabled. |
* |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* @param page Address of virtual page including VRN bits. |
* @param asid Address space identifier. |
* |
* @return True if page and asid match the page and asid of t, |
* false otherwise. |
* @return True if page and asid match the page and asid of t, false otherwise. |
*/ |
bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v) |
{ |
212,15 → 210,12 |
/** Set up one VHPT entry. |
* |
* @param v VHPT entry to be set up. |
* @param page Virtual address of the page mapped by the entry. |
* @param asid Address space identifier of the address space to which |
* page belongs. |
* @param frame Physical address of the frame to wich page is mapped. |
* @param flags Different flags for the mapping. |
* @param page Virtual address of the page mapped by the entry. |
* @param asid Address space identifier of the address space to which page belongs. |
* @param frame Physical address of the frame to wich page is mapped. |
* @param flags Different flags for the mapping. |
*/ |
void |
vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, |
int flags) |
void vhpt_set_record(vhpt_entry_t *v, uintptr_t page, asid_t asid, uintptr_t frame, int flags) |
{ |
region_register rr_save, rr; |
index_t vrn; |
254,8 → 249,7 |
v->word[3] = 0; |
v->present.p = true; |
v->present.ma = (flags & PAGE_CACHEABLE) ? |
MA_WRITEBACK : MA_UNCACHEABLE; |
v->present.ma = (flags & PAGE_CACHEABLE) ? MA_WRITEBACK : MA_UNCACHEABLE; |
v->present.a = false; /* not accessed */ |
v->present.d = false; /* not dirty */ |
v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; |
268,11 → 262,5 |
v->present.tag.tag_word = tag; |
} |
uintptr_t hw_map(uintptr_t physaddr, size_t size __attribute__ ((unused))) |
{ |
/* THIS is a dirty hack. */ |
return (uintptr_t)((uint64_t)(PA2KA(physaddr)) + VIO_OFFSET); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/src/start.S |
---|
32,15 → 32,19 |
#include <mm/asid.h> |
#define RR_MASK (0xFFFFFFFF00000002) |
#define RID_SHIFT 8 |
#define PS_SHIFT 2 |
#define RID_SHIFT 8 |
#define PS_SHIFT 2 |
#define KERNEL_TRANSLATION_I 0x0010000000000661 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
#define KERNEL_TRANSLATION_VIO 0x0010000000000671 |
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 |
#define KERNEL_TRANSLATION_FW 0x00100000F0000671 |
#define KERNEL_TRANSLATION_I 0x0010000000000661 |
#define KERNEL_TRANSLATION_D 0x0010000000000661 |
#define KERNEL_TRANSLATION_VIO 0x0010000000000671 |
#define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 |
#define VIO_OFFSET 0x0002000000000000 |
#define IO_OFFSET 0x0001000000000000 |
.section K_TEXT_START, "ax" |
.global kernel_image_start |
49,19 → 53,6 |
kernel_image_start: |
.auto |
#ifdef CONFIG_SMP |
# Identify self(CPU) in OS structures by ID / EID |
mov r9 = cr64 |
mov r10 = 1 |
movl r12 = 0xffffffff |
movl r8 = cpu_by_id_eid_list |
and r8 = r8, r12 |
shr r9 = r9, 16 |
add r8 = r8, r9 |
st1 [r8] = r10 |
#endif |
mov psr.l = r0 |
srlz.i |
srlz.d |
68,29 → 59,39 |
# Fill TR.i and TR.d using Region Register #VRN_KERNEL |
movl r8 = (VRN_KERNEL << VRN_SHIFT) |
mov r9 = rr[r8] |
movl r10 = (RR_MASK) |
and r9 = r10, r9 |
movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT)) |
or r9 = r10, r9 |
mov rr[r8] = r9 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) |
mov cr.ifa = r8 |
mov r11 = cr.itir |
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
mov r11 = cr.itir ;; |
movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT);; |
or r10 =r10 , r11 ;; |
mov cr.itir = r10;; |
movl r10 = (KERNEL_TRANSLATION_I) |
itr.i itr[r0] = r10 |
movl r10 = (KERNEL_TRANSLATION_D) |
itr.d dtr[r0] = r10 |
movl r7 = 1 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET |
mov cr.ifa = r8 |
97,13 → 98,15 |
movl r10 = (KERNEL_TRANSLATION_VIO) |
itr.d dtr[r7] = r10 |
mov r11 = cr.itir |
movl r10 = ~0xfc |
and r10 = r10, r11 |
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
mov r11 = cr.itir ;; |
movl r10 = ~0xfc;; |
and r10 =r10 , r11 ;; |
movl r11 = (IO_PAGE_WIDTH << PS_SHIFT);; |
or r10 =r10 , r11 ;; |
mov cr.itir = r10;; |
movl r7 = 2 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET |
mov cr.ifa = r8 |
110,26 → 113,12 |
movl r10 = (KERNEL_TRANSLATION_IO) |
itr.d dtr[r7] = r10 |
# Setup mapping for fimware arrea (also SAPIC) |
mov r11 = cr.itir |
movl r10 = ~0xfc |
and r10 = r10, r11 |
movl r11 = (FW_PAGE_WIDTH << PS_SHIFT) |
or r10 = r10, r11 |
mov cr.itir = r10 |
movl r7 = 3 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET |
mov cr.ifa = r8 |
movl r10 = (KERNEL_TRANSLATION_FW) |
itr.d dtr[r7] = r10 |
# Initialize PSR |
# initialize PSR |
movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */ |
mov r9 = psr |
or r10 = r10, r9 |
mov cr.ipsr = r10 |
mov cr.ifs = r0 |
139,14 → 128,11 |
srlz.i |
.explicit |
/* |
* Return From Interrupt is the only way to |
* fill the upper half word of PSR. |
* Return From Interupt is the only the way to fill upper half word of PSR. |
*/ |
rfi ;; |
rfi;; |
.global paging_start |
paging_start: |
154,64 → 140,45 |
* Now we are paging. |
*/ |
# Switch to register bank 1 |
# switch to register bank 1 |
bsw.1 |
#ifdef CONFIG_SMP |
# Am I BSP or AP? |
movl r20 = bsp_started ;; |
ld8 r20 = [r20] ;; |
cmp.eq p3, p2 = r20, r0 ;; |
#else |
cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */ |
#endif /* CONFIG_SMP */ |
# Initialize register stack |
# initialize register stack |
mov ar.rsc = r0 |
movl r8 = (VRN_KERNEL << VRN_SHIFT) ;; |
mov ar.bspstore = r8 |
loadrs |
# Initialize memory stack to some sane value |
# initialize memory stack to some sane value |
movl r12 = stack0 ;; |
add r12 = -16, r12 /* allocate a scratch area on the stack */ |
# Initialize gp (Global Pointer) register |
# initialize gp (Global Pointer) register |
movl r20 = (VRN_KERNEL << VRN_SHIFT);; |
or r20 = r20,r1;; |
movl r1 = _hardcoded_load_address |
/* |
* Initialize hardcoded_* variables. Do only BSP |
* Initialize hardcoded_* variables. |
*/ |
(p3) movl r14 = _hardcoded_ktext_size |
(p3) movl r15 = _hardcoded_kdata_size |
(p3) movl r16 = _hardcoded_load_address ;; |
(p3) addl r17 = @gprel(hardcoded_ktext_size), gp |
(p3) addl r18 = @gprel(hardcoded_kdata_size), gp |
(p3) addl r19 = @gprel(hardcoded_load_address), gp |
(p3) addl r21 = @gprel(bootinfo), gp |
movl r14 = _hardcoded_ktext_size |
movl r15 = _hardcoded_kdata_size |
movl r16 = _hardcoded_load_address ;; |
addl r17 = @gprel(hardcoded_ktext_size), gp |
addl r18 = @gprel(hardcoded_kdata_size), gp |
addl r19 = @gprel(hardcoded_load_address), gp |
addl r21 = @gprel(bootinfo), gp |
;; |
(p3) st8 [r17] = r14 |
(p3) st8 [r18] = r15 |
(p3) st8 [r19] = r16 |
(p3) st8 [r21] = r20 |
st8 [r17] = r14 |
st8 [r18] = r15 |
st8 [r19] = r16 |
st8 [r21] = r20 |
ssm (1 << 19) ;; /* Disable f32 - f127 */ |
srlz.i |
srlz.d ;; |
#ifdef CONFIG_SMP |
(p2) movl r18 = main_ap ;; |
(p2) mov b1 = r18 ;; |
(p2) br.call.sptk.many b0 = b1 |
# Mark that BSP is on |
mov r20 = 1 ;; |
movl r21 = bsp_started ;; |
st8 [r21] = r20 ;; |
#endif |
br.call.sptk.many b0 = arch_pre_main |
movl r18 = main_bsp ;; |
218,51 → 185,6 |
mov b1 = r18 ;; |
br.call.sptk.many b0 = b1 |
0: |
br 0b |
#ifdef CONFIG_SMP |
.align 4096 |
kernel_image_ap_start: |
.auto |
# Identify self(CPU) in OS structures by ID / EID |
mov r9 = cr64 |
mov r10 = 1 |
movl r12 = 0xffffffff |
movl r8 = cpu_by_id_eid_list |
and r8 = r8, r12 |
shr r9 = r9, 16 |
add r8 = r8, r9 |
st1 [r8] = r10 |
# Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list) |
kernel_image_ap_start_loop: |
movl r11 = kernel_image_ap_start_loop |
and r11 = r11, r12 |
mov b1 = r11 |
ld1 r20 = [r8] ;; |
movl r21 = 3 ;; |
cmp.eq p2, p3 = r20, r21 ;; |
(p3) br.call.sptk.many b0 = b1 |
movl r11 = kernel_image_start |
and r11 = r11, r12 |
mov b1 = r11 |
br.call.sptk.many b0 = b1 |
.align 16 |
.global bsp_started |
bsp_started: |
.space 8 |
.align 4096 |
.global cpu_by_id_eid_list |
cpu_by_id_eid_list: |
.space 65536 |
#endif /* CONFIG_SMP */ |
/branches/dd/kernel/arch/ia64/src/interrupt.c |
---|
53,7 → 53,6 |
#include <ipc/irq.h> |
#include <ipc/ipc.h> |
#include <synch/spinlock.h> |
#include <mm/tlb.h> |
#define VECTORS_64_BUNDLE 20 |
#define VECTORS_16_BUNDLE 48 |
186,21 → 185,21 |
break; |
} |
fault_if_from_uspace(istate, "General Exception (%s).", desc); |
fault_if_from_uspace(istate, "General Exception (%s)", desc); |
dump_interrupted_context(istate); |
panic("General Exception (%s).", desc); |
panic("General Exception (%s)\n", desc); |
} |
void disabled_fp_register(uint64_t vector, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
fault_if_from_uspace(istate, "Interruption: %#hx (%s)", |
(uint16_t) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s).", (uint16_t) vector, |
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
vector_to_string(vector)); |
#endif |
} |
228,82 → 227,40 |
void universal_handler(uint64_t vector, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Interruption: %#hx (%s).", |
fault_if_from_uspace(istate, "Interruption: %#hx (%s)\n", |
(uint16_t) vector, vector_to_string(vector)); |
dump_interrupted_context(istate); |
panic("Interruption: %#hx (%s).", (uint16_t) vector, |
panic("Interruption: %#hx (%s)\n", (uint16_t) vector, |
vector_to_string(vector)); |
} |
static void end_of_local_irq(void) |
{ |
asm volatile ("mov cr.eoi=r0;;"); |
} |
void external_interrupt(uint64_t vector, istate_t *istate) |
{ |
irq_t *irq; |
cr_ivr_t ivr; |
irq_t *irq; |
ivr.value = ivr_read(); |
srlz_d(); |
switch (ivr.vector) { |
case INTERRUPT_SPURIOUS: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
switch (ivr.vector) { |
case INTERRUPT_SPURIOUS: |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt\n", CPU->id); |
printf("cpu%d: spurious interrupt\n", CPU->id); |
#endif |
break; |
break; |
#ifdef CONFIG_SMP |
case VECTOR_TLB_SHOOTDOWN_IPI: |
tlb_shootdown_ipi_recv(); |
end_of_local_irq(); |
break; |
#endif |
case INTERRUPT_TIMER: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
irq->handler(irq); |
spinlock_unlock(&irq->lock); |
} else { |
panic("Unhandled Internal Timer Interrupt (%d).", |
default: |
panic("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
break; |
} |
break; |
default: |
irq = irq_dispatch_and_lock(ivr.vector); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
end_of_local_irq(); |
} |
irq->handler(irq); |
if (!irq->preack) |
end_of_local_irq(); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Unhandled interrupt. |
*/ |
end_of_local_irq(); |
#ifdef CONFIG_DEBUG |
printf("\nUnhandled External Interrupt Vector %d\n", |
ivr.vector); |
#endif |
} |
break; |
} |
} |
void trap_virtual_enable_irqs(uint16_t irqmask) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/src/cpu/cpu.c |
---|
70,8 → 70,8 |
} |
printf("cpu%d: %s (%s), archrev=%d, model=%d, revision=%d\n", CPU->id, |
family_str, vendor, CPU->arch.cpuid3.archrev, |
CPU->arch.cpuid3.model, CPU->arch.cpuid3.revision); |
family_str, vendor, CPU->arch.cpuid3.archrev, CPU->arch.cpuid3.model, |
CPU->arch.cpuid3.revision); |
} |
/** @} |
/branches/dd/kernel/arch/ia64/src/drivers/ega.c |
---|
0,0 → 1,139 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief EGA driver. |
*/ |
#include <putchar.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/mm/page.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/drivers/ega.h> |
/* |
* The EGA driver. |
* Simple and short. Function for displaying characters and "scrolling". |
*/ |
SPINLOCK_INITIALIZE(egalock); |
static uint32_t ega_cursor; |
static uint8_t *videoram; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
void ega_init(void) |
{ |
videoram = (uint8_t *) (VIDEORAM); |
/* |
* Clear the screen. |
*/ |
_memsetw((uintptr_t) videoram, SCREEN, 0x0720); |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
#ifndef CONFIG_FB |
putchar('\n'); |
#endif |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
videoram[ega_cursor * 2 + 1] = 7; |
} |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
{ |
if (ega_cursor < SCREEN) |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
_memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d, const char ch) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&egalock); |
switch (ch) { |
case '\n': |
ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW; |
break; |
case '\t': |
ega_cursor = (ega_cursor + 8) - ega_cursor % 8; |
break; |
case '\b': |
if (ega_cursor % ROW) |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
spinlock_unlock(&egalock); |
interrupts_restore(ipl); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/src/drivers/it.c |
---|
44,44 → 44,25 |
#include <ddi/device.h> |
#include <arch.h> |
#define IT_SERVICE_CLOCKS 64 |
#define IT_SERVICE_CLOCKS 64 |
#define FREQ_NUMERATOR_SHIFT 32 |
#define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL |
#define FREQ_DENOMINATOR_SHIFT 0 |
#define FREQ_DENOMINATOR_MASK 0xffffffffULL |
uint64_t it_delta; |
static irq_t it_irq; |
static irq_ownership_t it_claim(irq_t *); |
static void it_interrupt(irq_t *); |
static irq_ownership_t it_claim(void); |
static void it_interrupt(irq_t *irq, void *arg, ...); |
/** Initialize Interval Timer. */ |
void it_init(void) |
{ |
cr_itv_t itv; |
if (config.cpu_active == 1) { |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
uint64_t base_freq; |
base_freq = ((bootinfo->freq_scale) & FREQ_NUMERATOR_MASK) >> |
FREQ_NUMERATOR_SHIFT; |
base_freq *= bootinfo->sys_freq; |
base_freq /= ((bootinfo->freq_scale) & FREQ_DENOMINATOR_MASK) >> |
FREQ_DENOMINATOR_SHIFT; |
it_delta = base_freq / HZ; |
} |
irq_initialize(&it_irq); |
it_irq.inr = INTERRUPT_TIMER; |
it_irq.devno = device_assign_devno(); |
it_irq.claim = it_claim; |
it_irq.handler = it_interrupt; |
irq_register(&it_irq); |
/* initialize Interval Timer external interrupt vector */ |
itv.value = itv_read(); |
itv.vector = INTERRUPT_TIMER; |
104,13 → 85,13 |
* |
* @return Always IRQ_ACCEPT. |
*/ |
irq_ownership_t it_claim(irq_t *irq) |
irq_ownership_t it_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Process Interval Timer interrupt. */ |
void it_interrupt(irq_t *irq) |
void it_interrupt(irq_t *irq, void *arg, ...) |
{ |
int64_t c; |
int64_t m; |
/branches/dd/kernel/arch/ia64/src/ski/ski.c |
---|
44,9 → 44,8 |
#include <proc/thread.h> |
#include <synch/spinlock.h> |
#include <arch/asm.h> |
#include <arch/drivers/kbd.h> |
#define SKI_KBD_INR 0 |
#define SKI_KBD_INR 0 |
static irq_t ski_kbd_irq; |
static devno_t ski_kbd_devno; |
56,6 → 55,9 |
static bool kbd_disabled; |
static void ski_putchar(chardev_t *d, const char ch); |
static int32_t ski_getchar(void); |
/** Display character on debug console |
* |
* Use SSC (Simulator System Call) to |
64,21 → 66,19 |
* @param d Character device. |
* @param ch Character to be printed. |
*/ |
static void ski_putchar(chardev_t *d, const char ch, bool silent) |
void ski_putchar(chardev_t *d, const char ch) |
{ |
if (!silent) { |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r', false); |
} |
asm volatile ( |
"mov r15 = %0\n" |
"mov r32 = %1\n" /* r32 is in0 */ |
"break 0x80000\n" /* modifies r8 */ |
: |
: "i" (SKI_PUTCHAR), "r" (ch) |
: "r15", "in0", "r8" |
); |
if (ch == '\n') |
ski_putchar(d, '\r'); |
} |
/** Ask debug console if a key was pressed. |
90,7 → 90,7 |
* |
* @return ASCII code of pressed key or 0 if no key pressed. |
*/ |
static int32_t ski_getchar(void) |
int32_t ski_getchar(void) |
{ |
uint64_t ch; |
114,10 → 114,10 |
static char ski_getchar_blocking(chardev_t *d) |
{ |
int ch; |
while(!(ch = ski_getchar())); |
if (ch == '\r') |
while(!(ch = ski_getchar())) |
; |
if(ch == '\r') |
ch = '\n'; |
return (char) ch; |
} |
128,24 → 128,23 |
char ch; |
static char last; |
ipl_t ipl; |
ipl = interrupts_disable(); |
if (kbd_disabled) { |
interrupts_restore(ipl); |
return; |
} |
spinlock_lock(&ski_kbd_irq.lock); |
ch = ski_getchar(); |
if(ch == '\r') |
ch = '\n'; |
if (ch) { |
if (ski_kbd_irq.notif_cfg.notify && |
ski_kbd_irq.notif_cfg.answerbox) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, ch); |
/* XXX: send notification to userspace */ |
ipc_irq_send_notif(&ski_kbd_irq); |
} else { |
chardev_push_character(&ski_console, ch); |
} |
156,10 → 155,9 |
} |
if (last) { |
if (ski_kbd_irq.notif_cfg.notify && |
ski_kbd_irq.notif_cfg.answerbox) { |
if (ski_kbd_irq.notif_cfg.notify && ski_kbd_irq.notif_cfg.answerbox) { |
chardev_push_character(&ski_uconsole, 0); |
/* XXX: send notification to userspace */ |
ipc_irq_send_notif(&ski_kbd_irq); |
} |
last = 0; |
} |
177,7 → 175,7 |
/* Called from getc(). */ |
static void ski_kbd_disable(chardev_t *d) |
{ |
kbd_disabled = true; |
kbd_disabled = true; |
} |
/** Decline to service hardware IRQ. |
186,7 → 184,7 |
* |
* @return Always IRQ_DECLINE. |
*/ |
static irq_ownership_t ski_kbd_claim(irq_t *irq) |
static irq_ownership_t ski_kbd_claim(void) |
{ |
return IRQ_DECLINE; |
} |
229,9 → 227,6 |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.inr", NULL, SKI_KBD_INR); |
sysinfo_set_item_val("kbd.devno", NULL, ski_kbd_devno); |
sysinfo_set_item_val("kbd.type", NULL, KBD_SKI); |
sysinfo_set_item_val("fb", NULL, false); |
} |
void ski_kbd_grab(void) |
260,9 → 255,7 |
void kkbdpoll(void *arg) |
{ |
while (1) { |
if (!silent) { |
poll_keyboard(); |
} |
poll_keyboard(); |
thread_usleep(POLL_INTERVAL); |
} |
} |
/branches/dd/kernel/arch/ia64/src/ddi/ddi.c |
---|
1,6 → 1,5 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2008 Jakub vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
36,39 → 35,19 |
#include <ddi/ddi.h> |
#include <proc/task.h> |
#include <arch/types.h> |
#include <mm/slab.h> |
#include <errno.h> |
#define IO_MEMMAP_PAGES 16384 |
#define PORTS_PER_PAGE 4 |
/** Enable I/O space range for task. |
* |
* Interrupts are disabled and task is locked. |
* |
* @param task Task. |
* @param ioaddr Starting I/O space address. |
* @param size Size of the enabled I/O range. |
* @param task Task. |
* @param ioaddr Startign I/O space address. |
* @param size Size of the enabled I/O range. |
* |
* @return 0 on success or an error code from errno.h. |
*/ |
int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) |
{ |
if (!task->arch.iomap) { |
uint8_t *map; |
task->arch.iomap = malloc(sizeof(bitmap_t), 0); |
map = malloc(BITS2BYTES(IO_MEMMAP_PAGES), 0); |
if(!map) |
return ENOMEM; |
bitmap_initialize(task->arch.iomap, map, IO_MEMMAP_PAGES); |
bitmap_clear_range(task->arch.iomap, 0, IO_MEMMAP_PAGES); |
} |
uintptr_t iopage = ioaddr / PORTS_PER_PAGE; |
size = ALIGN_UP(size + ioaddr - 4 * iopage, PORTS_PER_PAGE); |
bitmap_set_range(task->arch.iomap, iopage, size / 4); |
return 0; |
} |
/branches/dd/kernel/arch/ia64/src/proc/scheduler.c |
---|
47,17 → 47,14 |
{ |
} |
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack |
* is mapped in DTR. |
*/ |
/** Prepare kernel stack pointers in bank 0 r22 and r23 and make sure the stack is mapped in DTR. */ |
void before_thread_runs_arch(void) |
{ |
uintptr_t base; |
base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
base = ALIGN_DOWN(config.base, 1<<KERNEL_PAGE_WIDTH); |
if ((uintptr_t) THREAD->kstack < base || |
(uintptr_t) THREAD->kstack > base + (1 << (KERNEL_PAGE_WIDTH))) { |
if ((uintptr_t) THREAD->kstack < base || (uintptr_t) THREAD->kstack > base + (1<<(KERNEL_PAGE_WIDTH))) { |
/* |
* Kernel stack of this thread is not mapped by DTR[TR_KERNEL]. |
* Use DTR[TR_KSTACK1] and DTR[TR_KSTACK2] to map it. |
67,11 → 64,8 |
dtr_purge((uintptr_t) THREAD->kstack, PAGE_WIDTH+1); |
/* insert DTR[TR_STACK1] and DTR[TR_STACK2] */ |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, |
KA2PA(THREAD->kstack), true, DTR_KSTACK1); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + |
PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, |
DTR_KSTACK2); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack, KA2PA(THREAD->kstack), true, DTR_KSTACK1); |
dtlb_kernel_mapping_insert((uintptr_t) THREAD->kstack + PAGE_SIZE, KA2PA(THREAD->kstack) + FRAME_SIZE, true, DTR_KSTACK2); |
} |
/* |
/branches/dd/kernel/arch/ia64/src/fpu_context.c |
---|
149,10 → 149,8 |
"stf.spill [%7] = f127, 0x80\n;;" |
: |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), |
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), |
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
); |
} |
269,16 → 267,14 |
"ldf.fill f127 = [%7], 0x80\n;;" |
: |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), |
"r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), |
"r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
: "r" (&((fctx->fr)[0])), "r" (&((fctx->fr)[1])), "r" (&((fctx->fr)[2])), "r" (&((fctx->fr)[3])), |
"r" (&((fctx->fr)[4])), "r" (&((fctx->fr)[5])), "r" (&((fctx->fr)[6])), "r" (&((fctx->fr)[7])) |
); |
} |
void fpu_enable(void) |
{ |
uint64_t a = 0; |
uint64_t a = 0 ; |
asm volatile ( |
"rsm %0 ;;" |
/branches/dd/kernel/arch/ia64/src/asm.S |
---|
51,7 → 51,7 |
adds r14 = 7, in1 |
mov r2 = ar.lc |
mov r8 = in0 |
mov r8 = in1 ;; |
and r14 = -8, r14 ;; |
cmp.ne p6, p7 = r14, in1 |
(p7) br.cond.dpnt 3f ;; |
63,7 → 63,7 |
(p6) mov r17 = r0 ;; |
(p6) mov ar.lc = r14 |
1: |
add r14 = r16, in1 |
add r14 = r16, r8 |
add r15 = r16, in0 |
adds r17 = 1, r17 ;; |
ld1 r14 = [r14] |
72,6 → 72,7 |
br.cloop.sptk.few 1b ;; |
2: |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
3: |
89,7 → 90,7 |
4: |
shladd r14 = r16, 3, r0 |
adds r16 = 1, r17 ;; |
add r15 = in1, r14 |
add r15 = r8, r14 |
add r14 = in0, r14 |
mov r17 = r16 ;; |
ld8 r15 = [r15] ;; |
103,7 → 104,7 |
cmp.eq p6, p7 = 0, r15 |
add in0 = r14, in0 |
adds r15 = -1, r15 |
add r17 = r14, in1 |
add r17 = r14, r8 |
(p6) br.cond.dpnt 2b ;; |
mov ar.lc = r15 |
6: |
115,6 → 116,7 |
st1 [r15] = r14 |
br.cloop.sptk.few 6b ;; |
mov ar.lc = r2 |
mov ar.pfs = loc0 |
br.ret.sptk.many rp |
128,10 → 130,6 |
memsetb: |
br _memsetb |
.global memsetw |
memsetw: |
br _memsetw |
.global cpu_halt |
cpu_halt: |
br cpu_halt |
165,9 → 163,6 |
xor r1 = r1, r1 |
/* r2 is defined to hold pcb_ptr - set it to 0 */ |
xor r2 = r2, r2 |
mov loc1 = cr.ifs |
movl loc2 = PFM_MASK ;; |
and loc1 = loc2, loc1 ;; |
/branches/dd/kernel/arch/ia64/src/putchar.c |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia64 |
* @{ |
*/ |
/** @file |
*/ |
#include <putchar.h> |
#include <arch/ski/ski.h> |
void putchar(const char ch) |
{ |
ski_write(ch); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia64/Makefile.inc |
---|
32,8 → 32,11 |
BFD_NAME = elf64-little |
BFD_ARCH = ia64-elf64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64 |
TOOLCHAIN_DIR = /usr/local/ia64 |
INIT0_ADDRESS = 0xe000000004404000 |
INIT0_SIZE = 0x100000 |
CMN1 = -mconstant-gp -fno-unwind-tables -mfixed-range=f32-f127 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
41,35 → 44,58 |
LFLAGS += -EL |
AFLAGS += -mconstant-gp |
DEFS += -D__64_BITS__ |
DEFS += -D__64_BITS__ -DINIT0_ADDRESS=$(INIT0_ADDRESS) -DINIT0_SIZE=$(INIT0_SIZE) -D$(MACHINE) |
## Compile with page hash table support. |
# |
CONFIG_PAGE_HT = y |
DEFS += -DCONFIG_PAGE_HT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/dummy.s \ |
arch/$(KARCH)/src/ia64.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ivt.S \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/vhpt.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/smp/smp.c \ |
arch/$(KARCH)/src/drivers/it.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/dummy.s \ |
arch/$(ARCH)/src/ia64.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/ivt.S \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/vhpt.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/it.c |
ifeq ($(MACHINE),ski) |
ARCH_SOURCES += arch/$(KARCH)/src/ski/ski.c |
ARCH_SOURCES += arch/$(ARCH)/src/ski/ski.c |
DEFS += -DSKI |
# BFD = elf64-ia64-little |
BFD = binary |
endif |
ifeq ($(MACHINE),i460GX) |
DEFS += -DI460GX |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/ega.c |
CONFIG_I8042 = y |
DEFS += -DI460GX -DCONFIG_I8042 |
BFD = binary |
endif |
/branches/dd/kernel/arch/arm32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
36,8 → 36,8 |
#ifndef KERN_arm32_FRAME_H_ |
#define KERN_arm32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4KB frames */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
44,8 → 44,8 |
#include <arch/types.h> |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#define BOOT_PAGE_TABLE_SIZE 0x4000 |
#define BOOT_PAGE_TABLE_ADDRESS 0x4000 |
#define BOOT_PAGE_TABLE_START_FRAME (BOOT_PAGE_TABLE_ADDRESS >> FRAME_WIDTH) |
#define BOOT_PAGE_TABLE_SIZE_IN_FRAMES (BOOT_PAGE_TABLE_SIZE >> FRAME_WIDTH) |
/branches/dd/kernel/arch/arm32/include/mm/page.h |
---|
43,6 → 43,8 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
193,8 → 195,9 |
static inline void set_ptl0_addr(pte_level0_t *pt) |
{ |
asm volatile ( |
"mcr p15, 0, %[pt], c2, c0, 0\n" |
:: [pt] "r" (pt) |
"mcr p15, 0, %0, c2, c0, 0 \n" |
: |
: "r"(pt) |
); |
} |
/branches/dd/kernel/arch/arm32/include/mm/tlb.h |
---|
36,6 → 36,9 |
#ifndef KERN_arm32_TLB_H_ |
#define KERN_arm32_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/dd/kernel/arch/arm32/include/asm/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
39,7 → 39,24 |
/** Size of a temporary stack used for initial kernel start. */ |
#define TEMP_STACK_SIZE 0x100 |
#ifndef __ASM__ |
/** Kernel entry point. |
* |
* Implemented in assembly. Copies boot_bootinfo (declared as bootinfo in |
* boot/arch/arm32/loader/main.c) to #bootinfo struct. Then jumps to |
* #arch_pre_main and #main_bsp. |
* |
* @param entry Entry point address (not used). |
* @param boot_bootinfo Struct holding information about loaded tasks. |
* @param bootinfo_size Size of the bootinfo structure. |
*/ |
extern void kernel_image_start(void *entry, void *boot_bootinfo, |
unsigned int bootinfo_size); |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/arm32/include/interrupt.h |
---|
37,7 → 37,6 |
#define KERN_arm32_INTERRUPT_H_ |
#include <arch/types.h> |
#include <arch/exception.h> |
/** Initial size of exception dispatch table. */ |
#define IVT_ITEMS 6 |
/branches/dd/kernel/arch/arm32/include/regutils.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** |
57,10 → 57,7 |
static inline uint32_t nm## _status_reg_read(void) \ |
{ \ |
uint32_t retval; \ |
asm volatile( \ |
"mrs %[retval], " #reg \ |
: [retval] "=r" (retval) \ |
); \ |
asm volatile("mrs %0, " #reg : "=r" (retval)); \ |
return retval; \ |
} |
67,10 → 64,7 |
#define GEN_STATUS_WRITE(nm,reg,fieldname, field) \ |
static inline void nm## _status_reg_ ##fieldname## _write(uint32_t value) \ |
{ \ |
asm volatile( \ |
"msr " #reg "_" #field ", %[value]" \ |
:: [value] "r" (value) \ |
); \ |
asm volatile("msr " #reg "_" #field ", %0" : : "r" (value)); \ |
} |
/branches/dd/kernel/arch/arm32/include/console.h |
---|
36,6 → 36,13 |
#ifndef KERN_arm32_CONSOLE_H_ |
#define KERN_arm32_CONSOLE_H_ |
/** Initializes console. |
* |
* @param devno Console device number. |
*/ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
/branches/dd/kernel/arch/arm32/include/boot.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
* @brief Bootinfo declarations. |
* |
* Reflects boot/arch/arm32/loader/main.h. |
*/ |
#ifndef KERN_arm32_BOOT_H_ |
#define KERN_arm32_BOOT_H_ |
#include <arch/types.h> |
/** Maximum number of tasks in the #bootinfo_t struct. */ |
#define TASKMAP_MAX_RECORDS 32 |
/** Struct holding information about single loaded uspace task. */ |
typedef struct { |
/** Address where the task was placed. */ |
uintptr_t addr; |
/** Size of the task's binary. */ |
uint32_t size; |
} utask_t; |
/** Struct holding information about loaded uspace tasks. */ |
typedef struct { |
/** Number of loaded tasks. */ |
uint32_t cnt; |
/** Array of loaded tasks. */ |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
/** Bootinfo that is filled in #kernel_image_start. */ |
extern bootinfo_t bootinfo; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/arm32/include/types.h |
---|
42,6 → 42,10 |
# define ATTRIBUTE_PACKED |
#endif |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
64,32 → 68,15 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "d" /**< Format for int32_t. */ |
#define PRId64 "lld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
#define PRIu8 "u" /**< Format for uint8_t. */ |
#define PRIu16 "u" /**< Format for uint16_t. */ |
#define PRIu32 "u" /**< Format for uint32_t. */ |
#define PRIu64 "llu" /**< Format for uint64_t. */ |
#define PRIun "u" /**< Format for unative_t. */ |
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ |
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ |
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ |
#define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
/** Page table entry. |
* |
* We have different structs for level 0 and level 1 page table entries. |
/branches/dd/kernel/arch/arm32/include/machine.h |
---|
102,15 → 102,18 |
extern uintptr_t machine_get_fb_address(void); |
#ifdef MACHINE_gxemul |
#define machine_console_init(devno) gxemul_console_init(devno) |
#define machine_hw_map_init gxemul_hw_map_init |
#define machine_timer_irq_start gxemul_timer_irq_start |
#define machine_cpu_halt gxemul_cpu_halt |
#define machine_get_memory_size gxemul_get_memory_size |
#define machine_debug_putc(ch) gxemul_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#ifdef MACHINE_GXEMUL_TESTARM |
#define machine_console_init(devno) gxemul_console_init(devno) |
#define machine_grab_console gxemul_grab_console |
#define machine_release_console gxemul_release_console |
#define machine_hw_map_init gxemul_hw_map_init |
#define machine_timer_irq_start gxemul_timer_irq_start |
#define machine_cpu_halt gxemul_cpu_halt |
#define machine_get_memory_size gxemul_get_memory_size |
#define machine_debug_putc(ch) gxemul_debug_putc(ch) |
#define machine_irq_exception(exc_no, istate) \ |
gxemul_irq_exception(exc_no, istate) |
#define machine_get_fb_address gxemul_get_fb_address |
#endif |
#endif |
/branches/dd/kernel/arch/arm32/include/memstr.h |
---|
38,10 → 38,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/branches/dd/kernel/arch/arm32/include/atomic.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Atomic operations. |
*/ |
42,26 → 42,26 |
* @param i Value to be added. |
* |
* @return Value after addition. |
* |
*/ |
static inline long atomic_add(atomic_t *val, int i) |
{ |
int ret; |
volatile long *mem = &(val->count); |
asm volatile ( |
"1:\n" |
"ldr r2, [%[mem]]\n" |
"add r3, r2, %[i]\n" |
"str r3, %[ret]\n" |
"swp r3, r3, [%[mem]]\n" |
"cmp r3, r2\n" |
"bne 1b\n" |
: [ret] "=m" (ret) |
: [mem] "r" (mem), [i] "r" (i) |
"1:\n" |
"ldr r2, [%1] \n" |
"add r3, r2, %2 \n" |
"str r3, %0 \n" |
"swp r3, r3, [%1] \n" |
"cmp r3, r2 \n" |
"bne 1b \n" |
: "=m" (ret) |
: "r" (mem), "r" (i) |
: "r3", "r2" |
); |
return ret; |
} |
/branches/dd/kernel/arch/arm32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
36,26 → 36,6 |
#ifndef KERN_arm32_ARCH_H_ |
#define KERN_arm32_ARCH_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo); |
#endif |
/** @} |
/branches/dd/kernel/arch/arm32/include/asm.h |
---|
26,10 → 26,10 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
/** @file |
* @brief Declarations of functions implemented in assembly. |
*/ |
36,7 → 36,6 |
#ifndef KERN_arm32_ASM_H_ |
#define KERN_arm32_ASM_H_ |
#include <typedefs.h> |
#include <arch/types.h> |
#include <arch/stack.h> |
#include <config.h> |
47,50 → 46,19 |
{ |
} |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
/** Return base address of current stack. |
* |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"and %[v], sp, %[size]\n" |
: [v] "=r" (v) |
: [size] "r" (~(STACK_SIZE - 1)) |
"and %0, sp, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE - 1)) |
); |
return v; |
} |
/branches/dd/kernel/arch/arm32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32 |
/** @addtogroup arm32 |
* @{ |
*/ |
/** @file |
39,16 → 39,13 |
/* |
* TODO: implement true ARM memory barriers for macros below. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define memory_barrier() asm volatile ("" ::: "memory") |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/dd/kernel/arch/arm32/src/mm/page_fault.c |
---|
40,7 → 40,6 |
#include <genarch/mm/page_pt.h> |
#include <arch.h> |
#include <interrupt.h> |
#include <print.h> |
/** Returns value stored in fault status register. |
* |
49,13 → 48,12 |
static inline fault_status_t read_fault_status_register(void) |
{ |
fault_status_union_t fsu; |
/* fault status is stored in CP15 register 5 */ |
asm volatile ( |
"mrc p15, 0, %[dummy], c5, c0, 0" |
: [dummy] "=r" (fsu.dummy) |
"mrc p15, 0, %0, c5, c0, 0" |
: "=r"(fsu.dummy) |
); |
return fsu.fs; |
} |
62,18 → 60,17 |
/** Returns FAR (fault address register) content. |
* |
* @return FAR (fault address register) content (address that caused a page |
* fault) |
* fault) |
*/ |
static inline uintptr_t read_fault_address_register(void) |
{ |
uintptr_t ret; |
/* fault adress is stored in CP15 register 6 */ |
asm volatile ( |
"mrc p15, 0, %[ret], c6, c0, 0" |
: [ret] "=r" (ret) |
"mrc p15, 0, %0, c6, c0, 0" |
: "=r"(ret) |
); |
return ret; |
} |
82,26 → 79,29 |
* @param instr Instruction |
* |
* @return true when instruction is load/store, false otherwise |
* |
*/ |
static inline bool is_load_store_instruction(instruction_t instr) |
{ |
/* load store immediate offset */ |
if (instr.type == 0x2) |
if (instr.type == 0x2) { |
return true; |
} |
/* load store register offset */ |
if ((instr.type == 0x3) && (instr.bit4 == 0)) |
if (instr.type == 0x3 && instr.bit4 == 0) { |
return true; |
} |
/* load store multiple */ |
if (instr.type == 0x4) |
if (instr.type == 0x4) { |
return true; |
} |
/* oprocessor load/store */ |
if (instr.type == 0x6) |
if (instr.type == 0x6) { |
return true; |
} |
return false; |
} |
114,11 → 114,12 |
static inline bool is_swap_instruction(instruction_t instr) |
{ |
/* swap, swapb instruction */ |
if ((instr.type == 0x0) && |
((instr.opcode == 0x8) || (instr.opcode == 0xa)) && |
(instr.access == 0x0) && (instr.bits567 == 0x4) && (instr.bit4 == 1)) |
if (instr.type == 0x0 && |
(instr.opcode == 0x8 || instr.opcode == 0xa) && |
instr.access == 0x0 && instr.bits567 == 0x4 && instr.bit4 == 1) { |
return true; |
} |
return false; |
} |
140,8 → 141,8 |
/* undefined instructions */ |
if (instr.condition == 0xf) { |
panic("page_fault - instruction does not access memory " |
"(instr_code: %x, badvaddr:%x).", instr, badvaddr); |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
160,7 → 161,7 |
} |
panic("page_fault - instruction doesn't access memory " |
"(instr_code: %x, badvaddr:%x).", instr, badvaddr); |
"(instr_code: %x, badvaddr:%x)", instr, badvaddr); |
return PF_ACCESS_EXEC; |
} |
186,8 → 187,8 |
"access:%d\n", istate->pc, badvaddr, fsr.status, fsr, |
access); |
fault_if_from_uspace(istate, "Page fault: %#x.", badvaddr); |
panic("Page fault."); |
fault_if_from_uspace(istate, "Page fault: %#x", badvaddr); |
panic("page fault\n"); |
} |
} |
203,7 → 204,7 |
if (ret == AS_PF_FAULT) { |
dprintf("prefetch_abort\n"); |
print_istate(istate); |
panic("page fault - prefetch_abort at address: %x.", |
panic("page fault - prefetch_abort at address: %x\n", |
istate->pc); |
} |
} |
/branches/dd/kernel/arch/arm32/src/mm/frame.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup arm32mm |
/** @addtogroup arm32mm |
* @{ |
*/ |
/** @file |
49,7 → 49,7 |
zone_create(0, ADDR2PFN(machine_get_memory_size()), |
BOOT_PAGE_TABLE_START_FRAME + BOOT_PAGE_TABLE_SIZE_IN_FRAMES, 0); |
last_frame = machine_get_memory_size(); |
/* blacklist boot page table */ |
frame_mark_unavailable(BOOT_PAGE_TABLE_START_FRAME, |
BOOT_PAGE_TABLE_SIZE_IN_FRAMES); |
/branches/dd/kernel/arch/arm32/src/mm/tlb.c |
---|
48,7 → 48,7 |
asm volatile ( |
"eor r1, r1\n" |
"mcr p15, 0, r1, c8, c7, 0\n" |
::: "r1" |
: : : "r1" |
); |
} |
68,8 → 68,9 |
static inline void invalidate_page(uintptr_t page) |
{ |
asm volatile ( |
"mcr p15, 0, %[page], c8, c7, 1\n" |
:: [page] "r" (page) |
"mcr p15, 0, %0, c8, c7, 1" |
: |
: "r" (page) |
); |
} |
80,7 → 81,7 |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid __attribute__((unused)), uintptr_t page, count_t cnt) |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
88,13 → 89,5 |
invalidate_page(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/arm32/src/mm/page.c |
---|
90,7 → 90,7 |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > |
KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) { |
panic("Unable to map physical memory %p (%d bytes).", |
panic("Unable to map physical memory %p (%d bytes)", |
physaddr, size) |
} |
/branches/dd/kernel/arch/arm32/src/arm32.c |
---|
34,6 → 34,7 |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <config.h> |
#include <arch/console.h> |
#include <ddi/device.h> |
47,22 → 48,22 |
#include <arch/regutils.h> |
#include <arch/machine.h> |
#include <userspace.h> |
#include <macros.h> |
#include <string.h> |
/** Performs arm32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
/** Information about loaded tasks. */ |
bootinfo_t bootinfo; |
/** Performs arm32 specific initialization before main_bsp() is called. */ |
void arch_pre_main(void) |
{ |
unsigned int i; |
init.cnt = bootinfo.cnt; |
for (i = 0; i < bootinfo.cnt; ++i) { |
init.tasks[i].addr = bootinfo.tasks[i].addr; |
init.tasks[i].size = bootinfo.tasks[i].size; |
} |
init.cnt = bootinfo->cnt; |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); ++i) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
} |
/** Performs arm32 specific initialization before mm is initialized. */ |
82,18 → 83,10 |
interrupt_init(); |
machine_console_init(device_assign_devno()); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
fb_properties_t prop = { |
.addr = machine_get_fb_address(), |
.offset = 0, |
.x = 640, |
.y = 480, |
.scan = 1920, |
.visual = VISUAL_BGR_8_8_8, |
}; |
fb_init(&prop); |
fb_init(machine_get_fb_address(), 640, 480, 1920, VISUAL_RGB_8_8_8); |
#endif |
} |
163,22 → 156,9 |
void arch_reboot() |
{ |
/* not implemented */ |
while (1); |
for (;;) |
; |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/arm32/src/cpu/cpu.c |
---|
36,7 → 36,7 |
#include <arch/cpu.h> |
#include <cpu.h> |
#include <arch.h> |
#include <print.h> |
#include <print.h> |
/** Number of indexes left out in the #imp_data array */ |
#define IMP_DATA_START_OFFSET 0x40 |
82,10 → 82,10 |
{ |
uint32_t ident; |
asm volatile ( |
"mrc p15, 0, %[ident], c0, c0, 0\n" |
: [ident] "=r" (ident) |
"mrc p15, 0, %0, c0, c0, 0\n" |
: "=r" (ident) |
); |
cpu->imp_num = ident >> 24; |
cpu->variant_num = (ident << 8) >> 28; |
cpu->arch_num = (ident << 12) >> 28; |
/branches/dd/kernel/arch/arm32/src/exception.c |
---|
40,7 → 40,6 |
#include <interrupt.h> |
#include <arch/machine.h> |
#include <arch/mm/page_fault.h> |
#include <arch/barrier.h> |
#include <print.h> |
#include <syscall/syscall.h> |
63,60 → 62,57 |
* |
* Temporary exception stack is used to save a few registers |
* before stack switch takes place. |
* |
*/ |
inline static void setup_stack_and_save_regs() |
{ |
asm volatile ( |
"ldr r13, =exc_stack\n" |
"stmfd r13!, {r0}\n" |
"mrs r0, spsr\n" |
"and r0, r0, #0x1f\n" |
"cmp r0, #0x10\n" |
"bne 1f\n" |
asm volatile( |
"ldr r13, =exc_stack \n" |
"stmfd r13!, {r0} \n" |
"mrs r0, spsr \n" |
"and r0, r0, #0x1f \n" |
"cmp r0, #0x10 \n" |
"bne 1f \n" |
/* prev mode was usermode */ |
"ldmfd r13!, {r0}\n" |
"ldr r13, =supervisor_sp\n" |
"ldr r13, [r13]\n" |
"stmfd r13!, {lr}\n" |
"stmfd r13!, {r0-r12}\n" |
"stmfd r13!, {r13, lr}^\n" |
"mrs r0, spsr\n" |
"stmfd r13!, {r0}\n" |
"b 2f\n" |
"ldmfd r13!, {r0} \n" |
"ldr r13, =supervisor_sp \n" |
"ldr r13, [r13] \n" |
"stmfd r13!, {lr} \n" |
"stmfd r13!, {r0-r12} \n" |
"stmfd r13!, {r13, lr}^ \n" |
"mrs r0, spsr \n" |
"stmfd r13!, {r0} \n" |
"b 2f \n" |
/* mode was not usermode */ |
"1:\n" |
"stmfd r13!, {r1, r2, r3}\n" |
"mrs r1, cpsr\n" |
"mov r2, lr\n" |
"bic r1, r1, #0x1f\n" |
"orr r1, r1, r0\n" |
"mrs r0, cpsr\n" |
"msr cpsr_c, r1\n" |
"mov r3, r13\n" |
"stmfd r13!, {r2}\n" |
"mov r2, lr\n" |
"stmfd r13!, {r4-r12}\n" |
"mov r1, r13\n" |
/* the following two lines are for debugging */ |
"mov sp, #0\n" |
"mov lr, #0\n" |
"msr cpsr_c, r0\n" |
"ldmfd r13!, {r4, r5, r6, r7}\n" |
"stmfd r1!, {r4, r5, r6}\n" |
"stmfd r1!, {r7}\n" |
"stmfd r1!, {r2}\n" |
"stmfd r1!, {r3}\n" |
"mrs r0, spsr\n" |
"stmfd r1!, {r0}\n" |
"mov r13, r1\n" |
"2:\n" |
"1:\n" |
"stmfd r13!, {r1, r2, r3} \n" |
"mrs r1, cpsr \n" |
"mov r2, lr \n" |
"bic r1, r1, #0x1f \n" |
"orr r1, r1, r0 \n" |
"mrs r0, cpsr \n" |
"msr cpsr_c, r1 \n" |
"mov r3, r13 \n" |
"stmfd r13!, {r2} \n" |
"mov r2, lr \n" |
"stmfd r13!, {r4-r12} \n" |
"mov r1, r13 \n" |
/* the following two lines are for debugging */ |
"mov sp, #0 \n" |
"mov lr, #0 \n" |
"msr cpsr_c, r0 \n" |
"ldmfd r13!, {r4, r5, r6, r7} \n" |
"stmfd r1!, {r4, r5, r6} \n" |
"stmfd r1!, {r7} \n" |
"stmfd r1!, {r2} \n" |
"stmfd r1!, {r3} \n" |
"mrs r0, spsr \n" |
"stmfd r1!, {r0} \n" |
"mov r13, r1 \n" |
"2:\n" |
); |
} |
192,13 → 188,10 |
} |
/** Calls exception dispatch routine. */ |
#define CALL_EXC_DISPATCH(exception) \ |
asm volatile ( \ |
"mov r0, %[exc]\n" \ |
"mov r1, r13\n" \ |
"bl exc_dispatch\n" \ |
:: [exc] "i" (exception) \ |
);\ |
#define CALL_EXC_DISPATCH(exception) \ |
asm("mov r0, %0" : : "i" (exception)); \ |
asm("mov r1, r13"); \ |
asm("bl exc_dispatch"); |
/** General exception handler. |
* |
207,9 → 200,9 |
* |
* @param exception Exception number. |
*/ |
#define PROCESS_EXCEPTION(exception) \ |
setup_stack_and_save_regs(); \ |
CALL_EXC_DISPATCH(exception) \ |
#define PROCESS_EXCEPTION(exception) \ |
setup_stack_and_save_regs(); \ |
CALL_EXC_DISPATCH(exception) \ |
load_regs(); |
/** Updates specified exception vector to jump to given handler. |
216,7 → 209,7 |
* |
* Addresses of handlers are stored in memory following exception vectors. |
*/ |
static void install_handler(unsigned handler_addr, unsigned *vector) |
static void install_handler (unsigned handler_addr, unsigned* vector) |
{ |
/* relative address (related to exc. vector) of the word |
* where handler's address is stored |
226,7 → 219,6 |
/* make it LDR instruction and store at exception vector */ |
*vector = handler_address_ptr | LDR_OPCODE; |
smc_coherence(*vector); |
/* store handler's address */ |
*(vector + EXC_VECTORS) = handler_addr; |
234,31 → 226,31 |
} |
/** Low-level Reset Exception handler. */ |
static void reset_exception_entry(void) |
static void reset_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_RESET); |
} |
/** Low-level Software Interrupt Exception handler. */ |
static void swi_exception_entry(void) |
static void swi_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_SWI); |
} |
/** Low-level Undefined Instruction Exception handler. */ |
static void undef_instr_exception_entry(void) |
static void undef_instr_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_UNDEF_INSTR); |
} |
/** Low-level Fast Interrupt Exception handler. */ |
static void fiq_exception_entry(void) |
static void fiq_exception_entry() |
{ |
PROCESS_EXCEPTION(EXC_FIQ); |
} |
/** Low-level Prefetch Abort Exception handler. */ |
static void prefetch_abort_exception_entry(void) |
static void prefetch_abort_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
PROCESS_EXCEPTION(EXC_PREFETCH_ABORT); |
265,7 → 257,7 |
} |
/** Low-level Data Abort Exception handler. */ |
static void data_abort_exception_entry(void) |
static void data_abort_exception_entry() |
{ |
asm("sub lr, lr, #8"); |
PROCESS_EXCEPTION(EXC_DATA_ABORT); |
277,7 → 269,7 |
* because of possible occurence of nested interrupt exception, which |
* would overwrite (and thus spoil) stack pointer. |
*/ |
static void irq_exception_entry(void) |
static void irq_exception_entry() |
{ |
asm("sub lr, lr, #4"); |
setup_stack_and_save_regs(); |
339,23 → 331,17 |
{ |
uint32_t control_reg; |
asm volatile ( |
"mrc p15, 0, %[control_reg], c1, c1" |
: [control_reg] "=r" (control_reg) |
); |
asm volatile("mrc p15, 0, %0, c1, c1" : "=r" (control_reg)); |
/* switch on the high vectors bit */ |
control_reg |= CP15_R1_HIGH_VECTORS_BIT; |
asm volatile ( |
"mcr p15, 0, %[control_reg], c1, c1" |
:: [control_reg] "r" (control_reg) |
); |
asm volatile("mcr p15, 0, %0, c1, c1" : : "r" (control_reg)); |
} |
#endif |
/** Initializes exception handling. |
* |
* |
* Installs low-level exception handlers and then registers |
* exceptions and their handlers to kernel exception dispatcher. |
*/ |
/branches/dd/kernel/arch/arm32/src/userspace.c |
---|
70,11 → 70,8 |
/* set first parameter */ |
ustate.r0 = (uintptr_t) kernel_uarg->uspace_uarg; |
/* %r1 is defined to hold pcb_ptr - set it to 0 */ |
ustate.r1 = 0; |
/* clear other registers */ |
ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
ustate.r1 = ustate.r2 = ustate.r3 = ustate.r4 = ustate.r5 = |
ustate.r6 = ustate.r7 = ustate.r8 = ustate.r9 = ustate.r10 = |
ustate.r11 = ustate.r12 = ustate.lr = 0; |
90,11 → 87,12 |
/* set user mode, set registers, jump */ |
asm volatile ( |
"mov sp, %[ustate]\n" |
"msr spsr_c, %[user_mode]\n" |
"ldmfd sp!, {r0-r12, sp, lr}^\n" |
"mov sp, %0 \n" |
"msr spsr_c, %1 \n" |
"ldmfd sp!, {r0-r12, sp, lr}^ \n" |
"ldmfd sp!, {pc}^\n" |
:: [ustate] "r" (&ustate), [user_mode] "r" (user_mode) |
: |
: "r" (&ustate), "r" (user_mode) |
); |
/* unreachable */ |
/branches/dd/kernel/arch/arm32/src/asm.S |
---|
45,8 → 45,7 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 /* save dst */ |
stmdb sp!, {r4, lr} |
beq 4f |
1: |
cmp r2, #0 |
59,8 → 58,8 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
mov r0, r1 |
ldmia sp!, {r4, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
95,5 → 94,5 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
mov r0, #0 |
ldmia sp!, {r4, r5, pc} |
mov r0, #0 |
ldmia sp!, {r4, pc} |
/branches/dd/kernel/arch/arm32/src/console.c |
---|
37,19 → 37,21 |
#include <arch/console.h> |
#include <arch/machine.h> |
#include <genarch/fb/fb.h> |
void console_init(devno_t devno) |
{ |
machine_console_init(devno); |
} |
/** Acquire console back for kernel. */ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
machine_grab_console(); |
} |
/** Return console to userspace. */ |
void arch_release_console(void) |
{ |
machine_release_console(); |
} |
/** @} |
/branches/dd/kernel/arch/arm32/src/start.S |
---|
40,12 → 40,30 |
mrs r3, cpsr |
bic r3, r3, #0x1f |
orr r3, r3, #0x13 |
msr cpsr_c, r3 |
msr cpsr_c, r3 |
ldr sp, =temp_stack |
cmp r2, #0 |
beq bootinfo_end |
ldr r3, =bootinfo |
bootinfo_loop: |
ldr r4, [r1] |
str r4, [r3] |
add r1, r1, #4 |
add r3, r3, #4 |
add r2, r2, #-4 |
cmp r2, #0 |
bne bootinfo_loop |
bootinfo_end: |
bl arch_pre_main |
bl main_bsp |
.space TEMP_STACK_SIZE |
56,3 → 74,4 |
supervisor_sp: |
.space 4 |
/branches/dd/kernel/arch/arm32/src/drivers/gxemul.c |
---|
34,6 → 34,7 |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/gxemul.h> |
#include <console/console.h> |
71,7 → 72,7 |
static void gxemul_kbd_enable(chardev_t *dev); |
static void gxemul_kbd_disable(chardev_t *dev); |
static void gxemul_write(chardev_t *dev, const char ch, bool silent); |
static void gxemul_write(chardev_t *dev, const char ch); |
static char gxemul_do_read(chardev_t *dev); |
static chardev_operations_t gxemul_ops = { |
132,10 → 133,9 |
* @param dev Not used. |
* @param ch Characted to be printed. |
*/ |
static void gxemul_write(chardev_t *dev, const char ch, bool silent) |
static void gxemul_write(chardev_t *dev, const char ch) |
{ |
if (!silent) |
*((char *) gxemul_hw_map.videoram) = ch; |
*((char *) gxemul_hw_map.videoram) = ch; |
} |
/** Enables gxemul keyboard (interrupt unmasked). |
183,26 → 183,54 |
/** Process keyboard interrupt. |
* |
* @param irq IRQ information. |
* @param arg Not used. |
*/ |
static void gxemul_irq_handler(irq_t *irq) |
static void gxemul_irq_handler(irq_t *irq, void *arg, ...) |
{ |
char ch = 0; |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) { |
ipc_irq_send_notif(irq); |
} else { |
char ch = 0; |
ch = *((char *) gxemul_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
ch = *((char *) gxemul_hw_map.kbd); |
if (ch == '\r') { |
ch = '\n'; |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
if (ch == 0x7f) { |
ch = '\b'; |
} |
chardev_push_character(&console, ch); |
} |
static irq_ownership_t gxemul_claim(irq_t *irq) |
static irq_ownership_t gxemul_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
/** Acquire console back for kernel. */ |
void gxemul_grab_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_console_irq.lock); |
gxemul_console_irq.notif_cfg.notify = false; |
spinlock_unlock(&gxemul_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Return console to userspace. */ |
void gxemul_release_console(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&gxemul_console_irq.lock); |
if (gxemul_console_irq.notif_cfg.answerbox) { |
gxemul_console_irq.notif_cfg.notify = true; |
} |
spinlock_unlock(&gxemul_console_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initializes console object representing gxemul console. |
* |
* @param devno device number. |
237,7 → 265,7 |
*((uint32_t*) gxemul_hw_map.rtc_freq) = frequency; |
} |
static irq_ownership_t gxemul_timer_claim(irq_t *irq) |
static irq_ownership_t gxemul_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
247,7 → 275,7 |
* @param irq Interrupt information. |
* @param arg Not used. |
*/ |
static void gxemul_timer_irq_handler(irq_t *irq) |
static void gxemul_timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
/* |
* We are holding a lock which prevents preemption. |
341,7 → 369,7 |
irq_t *irq = irq_dispatch_and_lock(i); |
if (irq) { |
/* The IRQ handler was found. */ |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* Spurious interrupt.*/ |
/branches/dd/kernel/arch/arm32/Makefile.inc |
---|
33,31 → 33,64 |
BFD_ARCH = arm |
BFD = binary |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm |
TOOLCHAIN_DIR = /usr/local/arm |
KERNEL_LOAD_ADDRESS = 0x80200000 |
ifeq ($(MACHINE), gxemul_testarm) |
DMACHINE = MACHINE_GXEMUL_TESTARM |
endif |
ATSIGN = % |
GCC_CFLAGS += -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ |
DEFS += -D__32_BITS__ -DKERNEL_LOAD_ADDRESS=$(KERNEL_LOAD_ADDRESS) -D$(DMACHINE) |
# Compile with framebuffer support |
ifeq ($(CONFIG_FB), y) |
DEFS += -DCONFIG_FB -DFB_INVERT_ENDIAN |
endif |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
# no HW support for ASIDs |
#CONFIG_ASID = y |
#CONFIG_ASID_FIFO = y |
## Compile with support with software division and multiplication. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/arm32.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/dummy.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/debug/print.c \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/page_fault.c \ |
arch/$(KARCH)/src/drivers/gxemul.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/arm32.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/dummy.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/debug/print.c \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/exception.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/page_fault.c |
ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += arch/$(ARCH)/src/drivers/gxemul.c |
endif |
/branches/dd/kernel/arch/arm32/_link.ld.in |
---|
1,16 → 1,15 |
/* |
* ARM linker script |
* |
* ARM linker script |
* |
* kernel text |
* kernel data |
* |
* |
*/ |
#define KERNEL_LOAD_ADDRESS 0x80200000 |
OUTPUT_ARCH(arm) |
ENTRY(kernel_image_start) |
ENTRY(kernel_image_start) |
SECTIONS { |
. = KERNEL_LOAD_ADDRESS; |
.text : { |
20,29 → 19,29 |
} |
.data : { |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
LONG(KERNEL_LOAD_ADDRESS); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.rodata*); |
*(.sdata); |
*(.reginfo); |
symbol_table = .; |
*(symtab.*); |
*(symtab.*); |
} |
.sbss : { |
*(.sbss); |
*(.scommon); |
} |
kdata_end = .; |
/DISCARD/ : { |
*(.mdebug*); |
*(.pdr); |
49,4 → 48,5 |
*(.comment); |
*(.note); |
} |
} |
/branches/dd/kernel/arch/amd64/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64mm |
/** @addtogroup amd64mm |
* @{ |
*/ |
/** @file |
39,8 → 39,8 |
#include <arch/types.h> |
#endif /* __ASM__ */ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifndef __ASM__ |
extern uintptr_t last_frame; |
/branches/dd/kernel/arch/amd64/include/mm/page.h |
---|
52,6 → 52,8 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dd/kernel/arch/amd64/include/mm/tlb.h |
---|
35,6 → 35,9 |
#ifndef KERN_amd64_TLB_H_ |
#define KERN_amd64_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/dd/kernel/arch/amd64/include/interrupt.h |
---|
71,6 → 71,7 |
/** This is passed to interrupt handlers */ |
typedef struct { |
uint64_t rax; |
uint64_t rbx; |
uint64_t rcx; |
uint64_t rdx; |
uint64_t rsi; |
79,6 → 80,11 |
uint64_t r9; |
uint64_t r10; |
uint64_t r11; |
uint64_t r12; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t rbp; |
uint64_t error_word; |
uint64_t rip; |
uint64_t cs; |
/branches/dd/kernel/arch/amd64/include/asm.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
36,8 → 36,6 |
#define KERN_amd64_ASM_H_ |
#include <config.h> |
#include <arch/types.h> |
#include <typedefs.h> |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
47,17 → 45,12 |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ( |
"andq %%rsp, %[v]\n" |
: [v] "=r" (v) |
: "0" (~((uint64_t) STACK_SIZE-1)) |
); |
asm volatile ("andq %%rsp, %0\n" : "=r" (v) : "0" (~((uint64_t)STACK_SIZE-1))); |
return v; |
} |
79,63 → 72,15 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline uint8_t inb(uint16_t port) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
/** Word from port |
* |
* Get word from port |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port)); |
return val; |
} |
/** Double word from port |
* |
* Get double word from port |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
} |
/** Byte to port |
* |
* Output byte to port |
142,48 → 87,12 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline void outb(uint16_t port, uint8_t val) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port)); |
} |
/** Word to port |
* |
* Output word to port |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Double word to port |
* |
* Output double word to port |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
/** Swap Hidden part of GS register with visible one */ |
static inline void swapgs(void) |
{ |
196,18 → 105,15 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
"popq %0\n" |
"sti\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
217,18 → 123,15 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
"popq %0\n" |
"cli\n" |
: [v] "=r" (v) |
); |
: "=r" (v) |
); |
return v; |
} |
237,14 → 140,13 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) { |
asm volatile ( |
"pushq %[ipl]\n" |
__asm__ volatile ( |
"pushq %0\n" |
"popfq\n" |
:: [ipl] "r" (ipl) |
); |
: : "r" (ipl) |
); |
} |
/** Return interrupt priority level. |
252,17 → 154,14 |
* Return EFLAFS. |
* |
* @return Current interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_read(void) { |
ipl_t v; |
asm volatile ( |
__asm__ volatile ( |
"pushfq\n" |
"popq %[v]\n" |
: [v] "=r" (v) |
"popq %0\n" |
: "=r" (v) |
); |
return v; |
} |
269,25 → 168,21 |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ( |
"wrmsr\n" |
:: "c" (msr), |
"a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
__asm__ volatile ( |
"wrmsr;" : : "c" (msr), |
"a" ((uint32_t)(value)), |
"d" ((uint32_t)(value >> 32)) |
); |
} |
static inline unative_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ( |
"rdmsr\n" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
__asm__ volatile ( |
"rdmsr;" : "=a"(ax), "=d"(dx) : "c" (msr) |
); |
return ((uint64_t)dx << 32) | ax; |
} |
294,29 → 189,29 |
/** Enable local APIC |
* |
* Enable local APIC in MSR. |
* |
*/ |
static inline void enable_l_apic_in_msr() |
{ |
asm volatile ( |
__asm__ volatile ( |
"movl $0x1b, %%ecx\n" |
"rdmsr\n" |
"orl $(1 << 11),%%eax\n" |
"orl $(1<<11),%%eax\n" |
"orl $(0xfee00000),%%eax\n" |
"wrmsr\n" |
::: "%eax","%ecx","%edx" |
); |
: |
: |
:"%eax","%ecx","%edx" |
); |
} |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%rip, %[ip]" |
: [ip] "=r" (ip) |
); |
__asm__ volatile ( |
"mov %%rip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
323,84 → 218,59 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*((unative_t *) addr)) |
); |
__asm__ volatile ("invlpg %0\n" :: "m" (*((unative_t *)addr))); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(struct ptr_16_64 *gdtr_reg) |
{ |
asm volatile ( |
"lgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
__asm__ volatile ("lgdtq %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(struct ptr_16_64 *gdtr_reg) |
{ |
asm volatile ( |
"sgdtq %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
__asm__ volatile ("sgdtq %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(struct ptr_16_64 *idtr_reg) |
{ |
asm volatile ( |
"lidtq %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg)); |
__asm__ volatile ("lidtq %0\n" : : "m" (*idtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
__asm__ volatile ("ltr %0" : : "r" (sel)); |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movq %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
__asm__ volatile ("movq %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ( \ |
"movq %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
{ \ |
__asm__ volatile ("movq %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
/branches/dd/kernel/arch/amd64/include/types.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
35,6 → 35,10 |
#ifndef KERN_amd64_TYPES_H_ |
#define KERN_amd64_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed int int32_t; |
57,34 → 61,14 |
typedef uint64_t unative_t; |
typedef int64_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
/**< Formats for uintptr_t, size_t, count_t and index_t */ |
#define PRIp "llx" |
#define PRIs "llu" |
#define PRIc "llu" |
#define PRIi "llu" |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
/**< Formats for (u)int8_t, (u)int16_t, (u)int32_t, (u)int64_t and (u)native_t */ |
#define PRId8 "d" |
#define PRId16 "d" |
#define PRId32 "d" |
#define PRId64 "lld" |
#define PRIdn "lld" |
#define PRIu8 "u" |
#define PRIu16 "u" |
#define PRIu32 "u" |
#define PRIu64 "llu" |
#define PRIun "llu" |
#define PRIx8 "x" |
#define PRIx16 "x" |
#define PRIx32 "x" |
#define PRIx64 "llx" |
#define PRIxn "llx" |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; |
/branches/dd/kernel/arch/amd64/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
41,29 → 41,17 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock incq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock incq %0\n" : "=m" (val->count)); |
#else |
asm volatile ( |
"incq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("incq %0\n" : "=m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock decq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock decq %0\n" : "=m" (val->count)); |
#else |
asm volatile ( |
"decq %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("decq %0\n" : "=m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
70,12 → 58,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddq %1, %0\n" |
: "=m" (val->count), "+r" (r) |
); |
return r; |
} |
84,23 → 72,23 |
long r = -1; |
asm volatile ( |
"lock xaddq %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddq %1, %0\n" |
: "=m" (val->count), "+r" (r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
static inline uint64_t test_and_set(atomic_t *val) { |
uint64_t v; |
asm volatile ( |
"movq $1, %[v]\n" |
"xchgq %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
"movq $1, %0\n" |
"xchgq %0, %1\n" |
: "=r" (v),"=m" (val->count) |
); |
return v; |
111,23 → 99,23 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint64_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"0:;" |
#ifdef CONFIG_HT |
"pause\n" |
"pause;" |
#endif |
"mov %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"mov %0, %1;" |
"testq %1, %1;" |
"jnz 0b;" /* Lightweight looping on locked spinlock */ |
"incq %[tmp]\n" /* now use the atomic operation */ |
"xchgq %[count], %[tmp]\n" |
"testq %[tmp], %[tmp]\n" |
"jnz 0b\n" |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
); |
"incq %1;" /* now use the atomic operation */ |
"xchgq %0, %1;" |
"testq %1, %1;" |
"jnz 0b;" |
: "=m"(val->count),"=r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
*/ |
/branches/dd/kernel/arch/amd64/include/memstr.h |
---|
35,13 → 35,110 |
#ifndef KERN_amd64_MEMSTR_H_ |
#define KERN_amd64_MEMSTR_H_ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
asm volatile( |
"rep movsq\n\t" |
"movq %4, %%rcx\n\t" |
"andq $7, %%rcx\n\t" |
"jz 1f\n\t" |
"rep movsb\n\t" |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t)(cnt / 8)), "g" ((unative_t)cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
return dst; |
} |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
unative_t d0, d1, d2; |
unative_t ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movq %3, %0\n\t" |
"addq $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" (src), "2" (dst), "3" ((unative_t)cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
unative_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" ((unative_t)cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/amd64/include/syscall.h |
---|
35,6 → 35,8 |
#ifndef KERN_amd64_SYSCALL_H_ |
#define KERN_amd64_SYSCALL_H_ |
#include <arch/types.h> |
extern void syscall_setup_cpu(void); |
#endif |
/branches/dd/kernel/arch/amd64/include/boot/boot.h |
---|
42,17 → 42,8 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#ifndef __ASM__ |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dd/kernel/arch/amd64/include/arch.h |
---|
35,10 → 35,6 |
#ifndef KERN_amd64_ARCH_H_ |
#define KERN_amd64_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/dd/kernel/arch/amd64/include/drivers/vesa.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006-2006 Jakub Vana |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_amd64_VESA_H_ |
#define KERN_amd64_VESA_H_ |
int vesa_present(void); |
void vesa_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/amd64/include/drivers/i8254.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8254.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/amd64/include/drivers/i8259.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8259.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/amd64/include/drivers/ega.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/ega.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/amd64/include/drivers/i8042.h |
---|
0,0 → 1,0 |
link ../../../ia32/include/drivers/i8042.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/amd64/src/asm_utils.S |
---|
26,17 → 26,23 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#define IREGISTER_SPACE 72 |
#define IREGISTER_SPACE 120 |
#define IOFFSET_RAX 0x0 |
#define IOFFSET_RCX 0x8 |
#define IOFFSET_RDX 0x10 |
#define IOFFSET_RSI 0x18 |
#define IOFFSET_RDI 0x20 |
#define IOFFSET_R8 0x28 |
#define IOFFSET_R9 0x30 |
#define IOFFSET_R10 0x38 |
#define IOFFSET_R11 0x40 |
#define IOFFSET_RAX 0x0 |
#define IOFFSET_RBX 0x8 |
#define IOFFSET_RCX 0x10 |
#define IOFFSET_RDX 0x18 |
#define IOFFSET_RSI 0x20 |
#define IOFFSET_RDI 0x28 |
#define IOFFSET_R8 0x30 |
#define IOFFSET_R9 0x38 |
#define IOFFSET_R10 0x40 |
#define IOFFSET_R11 0x48 |
#define IOFFSET_R12 0x50 |
#define IOFFSET_R13 0x58 |
#define IOFFSET_R14 0x60 |
#define IOFFSET_R15 0x68 |
#define IOFFSET_RBP 0x70 |
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word |
# and 1 means interrupt with error word |
59,8 → 65,6 |
.global get_cycle |
.global read_efer_flag |
.global set_efer_flag |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_to_uspace |
67,14 → 71,6 |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST %rdi |
#define MEMCPY_SRC %rsi |
#define MEMCPY_SIZE %rdx |
92,12 → 88,12 |
* @param MEMCPY_SRC Source address. |
* @param MEMCPY_SIZE Number of bytes to copy. |
* |
* @retrun MEMCPY_DST on success, 0 on failure. |
* @retrun MEMCPY_SRC on success, 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movq MEMCPY_DST, %rax |
movq MEMCPY_SRC, %rax |
movq MEMCPY_SIZE, %rcx |
shrq $3, %rcx /* size / 8 */ |
167,7 → 163,7 |
rdmsr |
ret |
# Push all volatile general purpose registers on stack |
# Push all general purpose registers on stack except %rbp, %rsp |
.macro save_all_gpr |
movq %rax, IOFFSET_RAX(%rsp) |
movq %rcx, IOFFSET_RCX(%rsp) |
178,6 → 174,14 |
movq %r9, IOFFSET_R9(%rsp) |
movq %r10, IOFFSET_R10(%rsp) |
movq %r11, IOFFSET_R11(%rsp) |
#ifdef CONFIG_DEBUG_ALLREGS |
movq %rbx, IOFFSET_RBX(%rsp) |
movq %rbp, IOFFSET_RBP(%rsp) |
movq %r12, IOFFSET_R12(%rsp) |
movq %r13, IOFFSET_R13(%rsp) |
movq %r14, IOFFSET_R14(%rsp) |
movq %r15, IOFFSET_R15(%rsp) |
#endif |
.endm |
.macro restore_all_gpr |
190,9 → 194,21 |
movq IOFFSET_R9(%rsp), %r9 |
movq IOFFSET_R10(%rsp), %r10 |
movq IOFFSET_R11(%rsp), %r11 |
#ifdef CONFIG_DEBUG_ALLREGS |
movq IOFFSET_RBX(%rsp), %rbx |
movq IOFFSET_RBP(%rsp), %rbp |
movq IOFFSET_R12(%rsp), %r12 |
movq IOFFSET_R13(%rsp), %r13 |
movq IOFFSET_R14(%rsp), %r14 |
movq IOFFSET_R15(%rsp), %r15 |
#endif |
.endm |
#define INTERRUPT_ALIGN 128 |
#ifdef CONFIG_DEBUG_ALLREGS |
# define INTERRUPT_ALIGN 256 |
#else |
# define INTERRUPT_ALIGN 128 |
#endif |
## Declare interrupt handlers |
# |
/branches/dd/kernel/arch/amd64/src/boot/boot.S |
---|
1,4 → 1,4 |
# |
# Copyright (c) 2005 Ondrej Palkovsky |
# Copyright (c) 2006 Martin Decky |
# Copyright (c) 2008 Jakub Jermar |
175,18 → 175,119 |
.code64 |
start64: |
movq $(PA2KA(START_STACK)), %rsp |
# arch_pre_main(grub_eax, grub_ebx) |
xorq %rdi, %rdi |
movl grub_eax, %edi |
xorq %rsi, %rsi |
movl grub_ebx, %esi |
call arch_pre_main |
call main_bsp |
# Not reached. |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory size or map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorq %rcx, %rcx |
movq %rcx, init |
jmp mods_end |
mods_valid: |
xorq %rcx, %rcx |
movl 20(%ebx), %ecx # mbi->mods_count |
movq %rcx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movq $init, %rdi |
mods_loop: |
xorq %rdx, %rdx |
movl 0(%esi), %edx # mods->mod_start |
movq $0xffff800000000000, %r10 |
addq %r10, %rdx |
movq %rdx, 8(%rdi) |
xorq %rdx, %rdx |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movq %rdx, 16(%rdi) |
addl $16, %esi |
addq $16, %rdi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movq $e820table, %rdi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%rdi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%rdi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%rdi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%rdi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%rdi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addq $MEMMAP_E820_RECORD_SIZE, %rdi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movq $BOOT_OFFSET, %rsi |
movq $AP_BOOT_OFFSET, %rdi |
movq $_hardcoded_unmapped_size, %rcx |
rep movsb |
#endif |
call main_bsp # never returns |
cli |
hlt |
326,8 → 427,7 |
xor %dx, %dx |
int $0x10 |
cmp $0x00, %ah |
je vga_not_compat |
jmp vga_not_compat |
vga_compat: |
/branches/dd/kernel/arch/amd64/src/cpu/cpu.c |
---|
77,19 → 77,21 |
void cpu_setup_fpu(void) |
{ |
asm volatile ( |
"movq %%cr0, %%rax\n" |
"btsq $1, %%rax\n" /* cr0.mp */ |
"btrq $2, %%rax\n" /* cr0.em */ |
"movq %%rax, %%cr0\n" |
"movq %%cr4, %%rax\n" |
"bts $9, %%rax\n" /* cr4.osfxsr */ |
"movq %%rax, %%cr4\n" |
::: "%rax" |
); |
"movq %%cr0, %%rax;" |
"btsq $1, %%rax;" /* cr0.mp */ |
"btrq $2, %%rax;" /* cr0.em */ |
"movq %%rax, %%cr0;" |
"movq %%cr4, %%rax;" |
"bts $9, %%rax;" /* cr4.osfxsr */ |
"movq %%rax, %%cr4;" |
: |
: |
:"%rax" |
); |
} |
/** Set the TS flag to 1. |
/** Set the TS flag to 1. |
* |
* If a thread accesses coprocessor, exception is run, which |
* does a lazy fpu context switch. |
97,22 → 99,26 |
*/ |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"bts $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
asm volatile ( |
"mov %%cr0,%%rax;" |
"bts $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%rax\n" |
"btr $3, %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
); |
asm volatile ( |
"mov %%cr0,%%rax;" |
"btr $3,%%rax;" |
"mov %%rax,%%cr0;" |
: |
: |
:"%rax" |
); |
} |
void cpu_arch_init(void) |
/branches/dd/kernel/arch/amd64/src/debugger.c |
---|
54,8 → 54,6 |
static bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
64,6 → 62,8 |
.argc = 0, |
}; |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
static int cmd_del_breakpoint(cmd_arg_t *argv); |
static cmd_arg_t del_argv = { |
.type = ARG_TYPE_INT |
99,8 → 99,36 |
.argv = &addw_argv |
}; |
#endif /* CONFIG_KCONSOLE */ |
#endif |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
if (sizeof(void *) == 4) { |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
} else { |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
} |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
if (sizeof(void *) == 4) |
printf("%-2u %-5d %#10zx %s\n", i, breakpoints[i].counter, |
breakpoints[i].address, symbol); |
else |
printf("%-2u %-5d %#18zx %s\n", i, breakpoints[i].counter, |
breakpoints[i].address, symbol); |
} |
return 1; |
} |
/* Setup DR register according to table */ |
static void setup_dr(int curidx) |
{ |
134,23 → 162,19 |
if ((flags & BKPOINT_INSTR)) { |
; |
} else { |
#ifdef __32_BITS__ |
dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx); |
#endif |
#ifdef __64_BITS__ |
dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx); |
#endif |
if (sizeof(int) == 4) |
dr7 |= ((unative_t) 0x3) << (18 + 4*curidx); |
else /* 8 */ |
dr7 |= ((unative_t) 0x2) << (18 + 4*curidx); |
if ((flags & BKPOINT_WRITE)) |
dr7 |= ((unative_t) 0x1) << (16 + 4 * curidx); |
dr7 |= ((unative_t) 0x1) << (16 + 4*curidx); |
else if ((flags & BKPOINT_READ_WRITE)) |
dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx); |
dr7 |= ((unative_t) 0x3) << (16 + 4*curidx); |
} |
/* Enable global breakpoint */ |
dr7 |= 0x2 << (curidx * 2); |
dr7 |= 0x2 << (curidx*2); |
write_dr7(dr7); |
201,16 → 225,16 |
/* Send IPI */ |
#ifdef CONFIG_SMP |
// ipi_broadcast(VECTOR_DEBUG_IPI); |
// ipi_broadcast(VECTOR_DEBUG_IPI); |
#endif |
return curidx; |
} |
#ifdef __64_BITS__ |
#define getip(x) ((x)->rip) |
#ifdef amd64 |
# define getip(x) ((x)->rip) |
#else |
#define getip(x) ((x)->eip) |
# define getip(x) ((x)->eip) |
#endif |
static void handle_exception(int slot, istate_t *istate) |
222,21 → 246,19 |
if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) { |
if (*((unative_t *) breakpoints[slot].address) != 0) |
return; |
printf("*** Found ZERO on address %lx (slot %d) ***\n", |
breakpoints[slot].address, slot); |
printf("**** Found ZERO on address %lx (slot %d) ****\n", |
breakpoints[slot].address, slot); |
} else { |
printf("Data watchpoint - new data: %lx\n", |
*((unative_t *) breakpoints[slot].address)); |
*((unative_t *) breakpoints[slot].address)); |
} |
} |
printf("Reached breakpoint %d:%lx(%s)\n", slot, getip(istate), |
get_symtab_entry(getip(istate))); |
#ifdef CONFIG_KCONSOLE |
atomic_set(&haltstate, 1); |
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false); |
atomic_set(&haltstate, 0); |
#endif |
get_symtab_entry(getip(istate))); |
printf("***Type 'exit' to exit kconsole.\n"); |
atomic_set(&haltstate,1); |
kconsole((void *) "debug"); |
atomic_set(&haltstate,0); |
} |
void breakpoint_del(int slot) |
265,8 → 287,42 |
#endif |
} |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif |
static void debug_exception(int n __attribute__((unused)), istate_t *istate) |
{ |
unative_t dr6; |
273,7 → 329,7 |
int i; |
/* Set RF to restart the instruction */ |
#ifdef __64_BITS__ |
#ifdef amd64 |
istate->rflags |= RFLAGS_RF; |
#else |
istate->eflags |= EFLAGS_RF; |
291,9 → 347,7 |
} |
#ifdef CONFIG_SMP |
static void |
debug_ipi(int n __attribute__((unused)), |
istate_t *istate __attribute__((unused))) |
static void debug_ipi(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
{ |
int i; |
309,103 → 363,34 |
{ |
int i; |
for (i = 0; i < BKPOINTS_MAX; i++) |
for (i=0; i<BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
printf("Cannot register command %s\n", bkpts_info.name); |
panic("could not register command %s\n", bkpts_info.name); |
#ifndef CONFIG_DEBUG_AS_WATCHPOINT |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
printf("Cannot register command %s\n", delbkpt_info.name); |
panic("could not register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
printf("Cannot register command %s\n", addbkpt_info.name); |
panic("could not register command %s\n", addbkpt_info.name); |
cmd_initialize(&addwatchp_info); |
if (!cmd_register(&addwatchp_info)) |
printf("Cannot register command %s\n", addwatchp_info.name); |
#endif /* CONFIG_KCONSOLE */ |
panic("could not register command %s\n", addwatchp_info.name); |
#endif |
exc_register(VECTOR_DEBUG, "debugger", debug_exception); |
exc_register(VECTOR_DEBUG, "debugger", |
debug_exception); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi); |
exc_register(VECTOR_DEBUG_IPI, "debugger_smp", |
debug_ipi); |
#endif |
} |
#ifdef CONFIG_KCONSOLE |
/** Print table of active breakpoints */ |
int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) |
{ |
unsigned int i; |
char *symbol; |
#ifdef __32_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ---------- ---------\n"); |
#endif |
#ifdef __64_BITS__ |
printf("# Count Address In symbol\n"); |
printf("-- ----- ------------------ ---------\n"); |
#endif |
for (i = 0; i < BKPOINTS_MAX; i++) |
if (breakpoints[i].address) { |
symbol = get_symtab_entry(breakpoints[i].address); |
#ifdef __32_BITS__ |
printf("%-2u %-5d %#10zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
#ifdef __64_BITS__ |
printf("%-2u %-5d %#18zx %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
symbol); |
#endif |
} |
return 1; |
} |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
unative_t bpno = argv->intval; |
if (bpno > BKPOINTS_MAX) { |
printf("Invalid breakpoint number.\n"); |
return 0; |
} |
breakpoint_del(argv->intval); |
return 1; |
} |
/** Add new breakpoint to table */ |
static int cmd_add_breakpoint(cmd_arg_t *argv) |
{ |
int flags; |
int id; |
if (argv == &add_argv) { |
flags = BKPOINT_INSTR; |
} else { /* addwatchp */ |
flags = BKPOINT_WRITE; |
} |
printf("Adding breakpoint on address: %p\n", argv->intval); |
id = breakpoint_add((void *)argv->intval, flags, -1); |
if (id < 0) |
printf("Add breakpoint failed.\n"); |
else |
printf("Added breakpoint %d.\n", id); |
return 1; |
} |
#endif /* CONFIG_KCONSOLE */ |
/** @} |
*/ |
/branches/dd/kernel/arch/amd64/src/mm/page.c |
---|
180,7 → 180,7 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page table entry."); |
panic("Reserved bit set in page table entry.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
190,11 → 190,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(n, istate); |
printf("Page fault address: %llx.\n", page); |
panic("Page fault."); |
printf("Page fault address: %llx\n", page); |
panic("page fault\n"); |
} |
} |
202,7 → 202,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
/branches/dd/kernel/arch/amd64/src/amd64.c |
---|
39,15 → 39,11 |
#include <config.h> |
#include <proc/thread.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/kbd/i8042.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
66,8 → 62,8 |
#include <console/console.h> |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
/** Disable I/O on non-privileged levels |
* |
* Clean IOPL(12,13) and NT(14) flags in EFLAGS register |
74,13 → 70,15 |
*/ |
static void clean_IOPL_NT_flags(void) |
{ |
asm volatile ( |
asm ( |
"pushfq\n" |
"pop %%rax\n" |
"and $~(0x7000), %%rax\n" |
"pushq %%rax\n" |
"popfq\n" |
::: "%rax" |
: |
: |
: "%rax" |
); |
} |
90,31 → 88,16 |
*/ |
static void clean_AM_flag(void) |
{ |
asm volatile ( |
asm ( |
"mov %%cr0, %%rax\n" |
"and $~(0x40000), %%rax\n" |
"mov %%rax, %%cr0\n" |
::: "%rax" |
: |
: |
: "%rax" |
); |
} |
/** Perform amd64-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
/* Enable no-execute pages */ |
156,7 → 139,7 |
vesa_init(); |
else |
#endif |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
ega_init(); /* video */ |
/* Enable debugger */ |
debugger_init(); |
189,28 → 172,8 |
void arch_post_smp_init(void) |
{ |
devno_t devno = device_assign_devno(); |
/* |
* Initialize the keyboard module and conect it to stdin. Then |
* initialize the i8042 controller and connect it to kbrdin. Enable |
* keyboard interrupts. |
*/ |
kbrd_init(stdin); |
(void) i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD, &kbrdin); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
/* keyboard controller */ |
i8042_init(device_assign_devno(), IRQ_KBD, device_assign_devno(), IRQ_MOUSE); |
} |
void calibrate_delay_loop(void) |
245,33 → 208,15 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
vesa_redraw(); |
#else |
ega_redraw(); |
#endif |
i8042_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/amd64/src/pm.c |
---|
155,7 → 155,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(tss_t), 0); |
memsetb((uintptr_t) t, sizeof(tss_t), 0); |
} |
/* |
209,7 → 209,7 |
tss_p = (struct tss *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("Cannot allocate TSS."); |
panic("could not allocate TSS\n"); |
} |
tss_initialize(tss_p); |
239,7 → 239,7 |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb(idt, sizeof(idt), 0); |
memsetb((uintptr_t) idt, sizeof(idt), 0); |
idtr_load(&idtr); |
interrupts_restore(ipl); |
/branches/dd/kernel/arch/amd64/src/proc/scheduler.c |
---|
39,6 → 39,7 |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/asm.h> |
#include <arch/debugger.h> |
#include <print.h> |
#include <arch/pm.h> |
#include <arch/ddi/ddi.h> |
67,6 → 68,13 |
/* TLS support - set FS to thread local storage */ |
write_msr(AMD_MSR_FS, THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
breakpoint_add(&((the_t *) THREAD->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, CPU->id); |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/dd/kernel/arch/amd64/src/proc/thread.c |
---|
46,7 → 46,7 |
* Kernel RSP can be precalculated at thread creation time. |
*/ |
t->arch.syscall_rsp[SYSCALL_KSTACK_RSP] = |
(uintptr_t) &t->kstack[PAGE_SIZE - sizeof(uint64_t)]; |
(uintptr_t)&t->kstack[PAGE_SIZE - sizeof(uint64_t)]; |
} |
/** @} |
/branches/dd/kernel/arch/amd64/src/interrupt.c |
---|
80,6 → 80,12 |
istate->rdi, istate->r8); |
printf("%%r9=%#llx, %%r10=%#llx, %%r11=%#llx\n", istate->r9, |
istate->r10, istate->r11); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%r12=%#llx, %%r13=%#llx, %%r14=%#llx\n", istate->r12, |
istate->r13, istate->r14); |
printf("%%r15=%#llx, %%rbx=%#llx, %%rbp=%#llx\n", istate->r15, |
istate->rbx, &istate->rbp); |
#endif |
printf("%%rsp=%#llx\n", &istate->stack[0]); |
} |
88,15 → 94,15 |
if (eoi_function) |
eoi_function(); |
else |
panic("No eoi_function."); |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(n, istate); |
panic("Unserviced interrupt."); |
panic("unserviced interrupt\n"); |
} |
/** General Protection Fault. */ |
120,37 → 126,35 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "General protection fault."); |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(n, istate); |
panic("General protection fault."); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Stack fault."); |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(n, istate); |
panic("Stack fault."); |
panic("stack fault\n"); |
} |
static void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
#ifdef CONFIG_SMP |
static void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
#endif |
/** Handler of IRQ exceptions */ |
static void irq_interrupt(int n, istate_t *istate) |
173,7 → 177,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
217,7 → 221,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("No enable_irqs_function."); |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
225,7 → 229,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("No disable_irqs_function."); |
panic("no disable_irqs_function\n"); |
} |
/** @} |
/branches/dd/kernel/arch/amd64/src/fpu_context.c |
---|
39,9 → 39,9 |
void fpu_context_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
"fxsave %0" |
: "=m"(*fctx) |
); |
} |
/** Restore FPU (mmx,sse) context using fxrstor instruction */ |
48,9 → 48,9 |
void fpu_context_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %[fctx]\n" |
: [fctx] "=m" (*fctx) |
); |
"fxrstor %0" |
: "=m"(*fctx) |
); |
} |
void fpu_init() |
57,7 → 57,7 |
{ |
/* TODO: Zero all SSE, MMX etc. registers */ |
asm volatile ( |
"fninit\n" |
"fninit;" |
); |
} |
/branches/dd/kernel/arch/amd64/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup amd64 |
/** @addtogroup amd64 |
* @{ |
*/ |
/** @file |
47,33 → 47,34 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
/* Clear CF, PF, AF, ZF, SF, DF, OF */ |
ipl = interrupts_disable(); |
/* Clear CF,PF,AF,ZF,SF,DF,OF */ |
ipl &= ~(0xcd4); |
asm volatile ("" |
"pushq %0\n" |
"pushq %1\n" |
"pushq %2\n" |
"pushq %3\n" |
"pushq %4\n" |
"movq %5, %%rax\n" |
"iretq\n" |
: : |
"i" (gdtselector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack+THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (gdtselector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
asm volatile ( |
"pushq %[udata_des]\n" |
"pushq %[stack_size]\n" |
"pushq %[ipl]\n" |
"pushq %[utext_des]\n" |
"pushq %[entry]\n" |
"movq %[uarg], %%rax\n" |
/* %rdi is defined to hold pcb_ptr - set it to 0 */ |
"xorq %%rdi, %%rdi\n" |
"iretq\n" |
:: [udata_des] "i" (gdtselector(UDATA_DES) | PL_USER), |
[stack_size] "r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (gdtselector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg) |
: "rax" |
); |
/* Unreachable */ |
while (1); |
for(;;) |
; |
} |
/** @} |
/branches/dd/kernel/arch/amd64/Makefile.inc |
---|
33,58 → 33,90 |
BFD_ARCH = i386:x86-64 |
BFD = binary |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64 |
TOOLCHAIN_DIR = /usr/local/amd64 |
FPU_NO_CFLAGS = -mno-sse -mno-sse2 |
CMN1 = -m64 -mcmodel=kernel -mno-red-zone -fno-unwind-tables |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
SUNCC_CFLAGS += -m64 -xmodel=kernel |
DEFS += -D__64_BITS__ |
DEFS += -DMACHINE=$(MACHINE) -D__64_BITS__ |
## Accepted CPUs |
# |
ifeq ($(PROCESSOR),opteron) |
ifeq ($(MACHINE),opteron) |
CMN2 := -march=opteron |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xtarget=opteron |
DEFS += -DFENCES=p4 |
endif |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with i8042 support. |
# |
CONFIG_I8042 = y |
DEFS += -DCONFIG_I8042 |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
ifeq ($(CONFIG_SIMICS_FIX),y) |
DEFS += -DCONFIG_SIMICS_FIX |
endif |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/boot/memmap.c \ |
arch/$(KARCH)/src/pm.c \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/vesa.c \ |
arch/$(KARCH)/src/drivers/i8254.c \ |
arch/$(KARCH)/src/drivers/i8259.c \ |
arch/$(KARCH)/src/delay.S \ |
arch/$(KARCH)/src/amd64.c \ |
arch/$(KARCH)/src/bios/bios.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/asm_utils.S \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/task.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/syscall.c \ |
arch/$(KARCH)/src/debugger.c |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/ega.c \ |
arch/$(ARCH)/src/drivers/vesa.c \ |
arch/$(ARCH)/src/drivers/i8254.c \ |
arch/$(ARCH)/src/drivers/i8259.c \ |
arch/$(ARCH)/src/delay.S \ |
arch/$(ARCH)/src/amd64.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/asm_utils.S \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/debugger.c |
ifeq ($(CONFIG_SMP),y) |
ARCH_SOURCES += \ |
arch/$(KARCH)/src/smp/ap.S \ |
arch/$(KARCH)/src/smp/apic.c \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/smp/mps.c \ |
arch/$(KARCH)/src/smp/smp.c |
arch/$(ARCH)/src/smp/ap.S \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c |
endif |
/branches/dd/kernel/arch/mips32/include/context_offset.h |
---|
76,17 → 76,26 |
#define EOFFSET_T5 0x30 |
#define EOFFSET_T6 0x34 |
#define EOFFSET_T7 0x38 |
#define EOFFSET_T8 0x3c |
#define EOFFSET_T9 0x40 |
#define EOFFSET_GP 0x44 |
#define EOFFSET_SP 0x48 |
#define EOFFSET_RA 0x4c |
#define EOFFSET_LO 0x50 |
#define EOFFSET_HI 0x54 |
#define EOFFSET_STATUS 0x58 |
#define EOFFSET_EPC 0x5c |
#define EOFFSET_K1 0x60 |
#define REGISTER_SPACE 100 |
#define EOFFSET_S0 0x3c |
#define EOFFSET_S1 0x40 |
#define EOFFSET_S2 0x44 |
#define EOFFSET_S3 0x48 |
#define EOFFSET_S4 0x4c |
#define EOFFSET_S5 0x50 |
#define EOFFSET_S6 0x54 |
#define EOFFSET_S7 0x58 |
#define EOFFSET_T8 0x5c |
#define EOFFSET_T9 0x60 |
#define EOFFSET_GP 0x64 |
#define EOFFSET_SP 0x68 |
#define EOFFSET_S8 0x6c |
#define EOFFSET_RA 0x70 |
#define EOFFSET_LO 0x74 |
#define EOFFSET_HI 0x78 |
#define EOFFSET_STATUS 0x7c |
#define EOFFSET_EPC 0x80 |
#define EOFFSET_K1 0x84 |
#define REGISTER_SPACE 136 |
#ifdef __ASM__ |
105,10 → 114,10 |
sw $s8,OFFSET_S8(\ctx) |
sw $gp,OFFSET_GP(\ctx) |
#ifndef KERNEL |
#ifndef KERNEL |
sw $k1,OFFSET_TLS(\ctx) |
#ifdef CONFIG_FPU |
# ifdef CONFIG_MIPS_FPU |
mfc1 $t0,$20 |
sw $t0, OFFSET_F20(\ctx) |
141,7 → 150,7 |
mfc1 $t0,$30 |
sw $t0, OFFSET_F30(\ctx) |
#endif /* CONFIG_FPU */ |
# endif /* CONFIG_MIPS_FPU */ |
#endif /* KERNEL */ |
sw $ra,OFFSET_PC(\ctx) |
163,7 → 172,7 |
#ifndef KERNEL |
lw $k1,OFFSET_TLS(\ctx) |
#ifdef CONFIG_FPU |
# ifdef CONFIG_MIPS_FPU |
lw $t0, OFFSET_F20(\ctx) |
mtc1 $t0,$20 |
196,9 → 205,9 |
lw $t0, OFFSET_F30(\ctx) |
mtc1 $t0,$30 |
#endif /* CONFIG_FPU */ |
# endif /* CONFIG_MIPS_FPU */ |
#endif /* KERNEL */ |
lw $ra,OFFSET_PC(\ctx) |
lw $sp,OFFSET_SP(\ctx) |
.endm |
/branches/dd/kernel/arch/mips32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
35,14 → 35,12 |
#ifndef KERN_mips32_FRAME_H_ |
#define KERN_mips32_FRAME_H_ |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 14 /* 16K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#include <typedefs.h> |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
/branches/dd/kernel/arch/mips32/include/mm/page.h |
---|
40,6 → 40,8 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
/branches/dd/kernel/arch/mips32/include/mm/tlb.h |
---|
35,9 → 35,6 |
#ifndef KERN_mips32_TLB_H_ |
#define KERN_mips32_TLB_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <arch/mm/asid.h> |
#include <arch/exception.h> |
#ifdef TLBCNT |
49,13 → 46,7 |
#define TLB_WIRED 1 |
#define TLB_KSTACK_WIRED_INDEX 0 |
#define TLB_PAGE_MASK_4K (0x000 << 13) |
#define TLB_PAGE_MASK_16K (0x003 << 13) |
#define TLB_PAGE_MASK_64K (0x00f << 13) |
#define TLB_PAGE_MASK_256K (0x03f << 13) |
#define TLB_PAGE_MASK_1M (0x0ff << 13) |
#define TLB_PAGE_MASK_4M (0x3ff << 13) |
#define TLB_PAGE_MASK_16M (0xfff << 13) |
#define TLB_PAGE_MASK_16K (0x3<<13) |
#define PAGE_UNCACHED 2 |
#define PAGE_CACHEABLE_EXC_WRITE 5 |
168,8 → 159,6 |
extern void tlb_invalid(istate_t *istate); |
extern void tlb_refill(istate_t *istate); |
extern void tlb_modified(istate_t *istate); |
extern void tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
extern void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
#endif |
/branches/dd/kernel/arch/mips32/include/mm/as.h |
---|
38,7 → 38,7 |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000 |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0x9fffffff |
#define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffff |
#define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x00000000 |
#define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0x7fffffff |
/branches/dd/kernel/arch/mips32/include/mm/asid.h |
---|
37,7 → 37,7 |
#include <arch/types.h> |
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */ |
#define ASID_MAX_ARCH 255 /* 2^8 - 1 */ |
typedef uint8_t asid_t; |
/branches/dd/kernel/arch/mips32/include/drivers/arc.h |
---|
0,0 → 1,267 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_mips32_ARC_H_ |
#define KERN_mips32_ARC_H_ |
#include <arch/types.h> |
#include <console/chardev.h> |
#define ARC_BASE_ADDR 0x1000; |
#define ARC_MAGIC 0x53435241 |
/* Frame size used by ARC */ |
#define ARC_FRAME 4096 |
typedef enum { |
CmResourceTypeNull = 0, |
CmResourceTypePort, |
CmResourceTypeInterrupt, |
CmResourceTypeMemory, |
CmResourceTypeDma, |
CmResourceTypeDeviceSpecific, |
CmResourceTypeVendor, |
CmResourceTypeProductName, |
CmResourceTypeSerialNumber |
} cm_resource_type; |
typedef struct { |
uint8_t type; |
uint8_t sharedisposition; |
uint16_t flags; |
union { |
struct { |
long long start; /* 64-bit phys address */ |
unsigned long length; |
}port; |
struct { |
unsigned long level; |
unsigned long vector; |
unsigned long reserved1; |
}interrupt; |
struct { |
long long start; /* 64-bit phys address */ |
unsigned long length; |
}memory; |
}u; |
} __attribute__ ((packed)) cm_resource_descriptor; |
typedef struct { |
uint16_t version; |
uint16_t revision; |
unsigned long count; |
cm_resource_descriptor descr[1]; |
} __attribute__ ((packed)) cm_resource_list; |
typedef enum { |
SystemClass = 0, |
ProcessorClass, |
CacheClass, |
AdapterClass, |
ControllerClass, |
PeripheralClass, |
MemoryClass |
} arc_component_class; |
typedef enum { |
ARC_type = 0, |
CPU_type, |
FPU_type, |
PrimaryICache, |
PrimaryDCache, |
SecondaryICache, |
SecondaryDCache, |
SecondaryCache, |
Memory, /* Not in NT PROM */ |
EISAAdapter, |
TCAdapter, |
SCSIAdapter, |
DTIAdapter, |
MultiFunctionAdapter, |
DiskController, |
TapeController, |
CDROMController, |
WORMController, |
SerialController, |
NetworkController, |
DisplayController, |
ParallelController, |
PointerController, |
KeyboardController, |
AudioController, |
OtherController, |
DiskPeripheral, |
FloppyDiskPeripheral, |
TapePeripheral, |
ModemPeripheral, |
MonitorPeripheral, |
PrinterPeripheral, |
PointerPeripheral, |
KeyboardPeripheral, |
TerminalPeripheral, |
LinePeripheral, |
NetworkPeripheral, |
OtherPeripheral, |
XTalkAdapter, |
PCIAdapter, |
GIOAdapter, |
TPUAdapter, |
Anonymous |
} arc_component_type; |
typedef enum { |
Failed = 1, |
ReadOnly = 2, |
Removable = 4, |
ConsoleIn = 8, |
ConsoleOut = 16, |
Input = 32, |
Output = 64 |
} arc_component_flags; |
typedef struct { |
arc_component_class class; |
arc_component_type type; |
arc_component_flags flags; |
uint16_t revision; |
uint16_t version; |
uint32_t key; |
uint32_t affinitymask; |
uint32_t configdatasize; |
uint32_t identifier_len; |
char *identifier; |
} __attribute__ ((packed)) arc_component; |
typedef struct { |
uint16_t year; |
uint16_t month; |
uint16_t day; |
uint16_t hour; |
uint16_t minutes; |
uint16_t seconds; |
uint16_t mseconds; |
} __attribute__ ((packed)) arc_timeinfo; |
/* This is the SGI block structure, WinNT has it different */ |
typedef enum { |
ExceptionBlock, |
SystemParameterBlock, |
FreeContiguous, |
FreeMemory, |
BadMemory, |
LoadedProgram, |
FirmwareTemporary, |
FirmwarePermanent |
} arc_memorytype_t; |
typedef struct { |
arc_memorytype_t type; |
uint32_t basepage; /* *4096 = baseaddr */ |
uint32_t basecount; |
} arc_memdescriptor_t; |
typedef struct { |
char vendorid[8]; |
char prodid[8]; |
} arc_sysid_t; |
typedef struct { |
long (*load)(void); /* ... */ |
long (*invoke)(uint32_t eaddr,uint32_t saddr,uint32_t argc,char **argv, |
char **envp); |
long (*execute)(char *path,uint32_t argc,char **argv,char **envp); |
void (*halt)(void); |
void (*powerdown)(void); |
void (*restart)(void); |
void (*reboot)(void); |
void (*enterinteractivemode)(void); |
long (*reserved)(void); |
/* 10 */ |
arc_component * (*getpeer)(arc_component *c); |
arc_component * (*getchild)(arc_component *c); |
arc_component * (*getparent)(arc_component *c); |
long (*getconfigurationdata)(void *configdata, arc_component *c); |
long (*addchild)(arc_component *c, arc_component *template, |
void *configdata); |
long (*deletecomponet)(arc_component *current); |
long (*getcomponent)(char *path); |
long (*saveconfiguration)(void); |
arc_sysid_t (*getsystemid)(void); |
arc_memdescriptor_t * (*getmemorydescriptor)(arc_memdescriptor_t *cur); |
/* 20 */ |
long (*reserved2)(void); |
arc_timeinfo * (*gettime)(void); |
uint32_t (*getrelativetime)(void); |
long (*getdirectoryentry)(); |
long (*open)(void); /* ... */ |
long (*close)(uint32_t fileid); |
long (*read)(uint32_t fileid,void *buf,uint32_t n,uint32_t *cnt); |
long (*getreadstatus)(uint32_t fileid); |
long (*write)(uint32_t fileid, void *buf,uint32_t n,uint32_t *cnt); |
long (*seek)(void); /* ... */ |
/* 30 */ |
long (*mount)(void); /* ... */ |
char * (*getenvironmentvariable)(char *name); |
char * (*setenvironmentvariable)(char *name, char *value); |
long (*getfileinformation)(void); /* ... */ |
long (*setfileinformation)(uint32_t fileid,uint32_t attflags,uint32_t attmask); |
void (*flushallcaches)(void); |
long (*testunicodecharacter)(void); /* ... */ |
long (*getdisplaystatus)(void); /* ... */ |
} arc_func_vector_t; |
typedef struct { |
uint32_t signature; |
uint32_t length; |
uint16_t version; |
uint16_t revision; |
void *restartblock; |
void *debugblock; |
void *gevector; |
void *utlbmissvector; |
uint32_t firmwarevectorlen; |
arc_func_vector_t *firmwarevector; |
uint32_t privvectorlen; |
void *privvector; |
uint32_t adaptercount; |
} __attribute__ ((packed)) arc_sbp; |
extern int arc_init(void); |
extern int arc_reboot(void); |
extern int arc_frame_init(void); |
extern int arc_console(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/include/drivers/serial.h |
---|
35,8 → 35,36 |
#ifndef KERN_mips32_SERIAL_H_ |
#define KERN_mips32_SERIAL_H_ |
#define SERIAL_ADDRESS 0x98000000 |
#include <console/chardev.h> |
#define SERIAL_MAX 4 |
#define SERIAL_COM1 0x3f8 |
#define SERIAL_COM1_IRQ 4 |
#define SERIAL_COM2 0x2f8 |
#define SERIAL_COM2_IRQ 3 |
#define P_WRITEB(where,what) (*((volatile char *) (0xB8000000+where))=what) |
#define P_READB(where) (*((volatile char *)(0xB8000000+where))) |
#define SERIAL_READ(x) P_READB(x) |
#define SERIAL_WRITE(x,c) P_WRITEB(x,c) |
/* Interrupt enable register */ |
#define SERIAL_READ_IER(x) (P_READB((x) + 1)) |
#define SERIAL_WRITE_IER(x,c) (P_WRITEB((x)+1,c)) |
/* Interrupt identification register */ |
#define SERIAL_READ_IIR(x) (P_READB((x) + 2)) |
/* Line status register */ |
#define SERIAL_READ_LSR(x) (P_READB((x) + 5)) |
#define TRANSMIT_EMPTY_BIT 5 |
typedef struct { |
int port; |
int irq; |
}serial_t; |
extern void serial_console(devno_t devno); |
extern int serial_init(void); |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/include/drivers/msim.h |
---|
35,11 → 35,6 |
#ifndef KERN_mips32_MSIM_H_ |
#define KERN_mips32_MSIM_H_ |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0x90000000 |
#define MSIM_KBD_ADDRESS 0x90000000 |
#define MSIM_KBD_IRQ 2 |
#include <console/chardev.h> |
void msim_console(devno_t devno); |
/branches/dd/kernel/arch/mips32/include/smp/dorder.h |
---|
File deleted |
/branches/dd/kernel/arch/mips32/include/smp/order.h |
---|
0,0 → 1,34 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_mips32_ORDER_H_ |
#define KERN_mips32_ORDER_H_ |
extern void ipi_broadcast_arch(int ipi); |
#endif |
/branches/dd/kernel/arch/mips32/include/interrupt.h |
---|
38,11 → 38,9 |
#include <typedefs.h> |
#include <arch/exception.h> |
#define IVT_ITEMS 32 |
#define IVT_FIRST 0 |
#define IVT_ITEMS 32 |
#define IVT_FIRST 0 |
#define VECTOR_TLB_SHOOTDOWN_IPI EXC_Int |
extern function virtual_timer_fnc; |
extern uint32_t count_hi; |
/branches/dd/kernel/arch/mips32/include/types.h |
---|
35,6 → 35,10 |
#ifndef KERN_mips32_TYPES_H_ |
#define KERN_mips32_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
57,32 → 61,14 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "ld" /**< Format for int32_t. */ |
#define PRId64 "lld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
#define PRIu8 "u" /**< Format for uint8_t. */ |
#define PRIu16 "u" /**< Format for uint16_t. */ |
#define PRIu32 "u" /**< Format for uint32_t. */ |
#define PRIu64 "llu" /**< Format for uint64_t. */ |
#define PRIun "u" /**< Format for unative_t. */ |
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ |
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ |
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ |
#define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
/** Page Table Entry. */ |
typedef struct { |
unsigned g : 1; /**< Global bit. */ |
/branches/dd/kernel/arch/mips32/include/exception.h |
---|
73,10 → 73,19 |
uint32_t t5; |
uint32_t t6; |
uint32_t t7; |
uint32_t s0; |
uint32_t s1; |
uint32_t s2; |
uint32_t s3; |
uint32_t s4; |
uint32_t s5; |
uint32_t s6; |
uint32_t s7; |
uint32_t t8; |
uint32_t t9; |
uint32_t gp; |
uint32_t sp; |
uint32_t s8; |
uint32_t ra; |
uint32_t lo; |
/branches/dd/kernel/arch/mips32/include/asm.h |
---|
36,7 → 36,6 |
#define KERN_mips32_ASM_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
56,11 → 55,7 |
{ |
uintptr_t v; |
asm volatile ( |
"and %0, $29, %1\n" |
: "=r" (v) |
: "r" (~(STACK_SIZE-1)) |
); |
asm volatile ("and %0, $29, %1\n" : "=r" (v) : "r" (~(STACK_SIZE-1))); |
return v; |
} |
68,44 → 63,13 |
extern void cpu_halt(void); |
extern void asm_delay_loop(uint32_t t); |
extern void userspace_asm(uintptr_t ustack, uintptr_t uspace_uarg, |
uintptr_t entry); |
uintptr_t entry); |
extern ipl_t interrupts_disable(void); |
extern ipl_t interrupts_enable(void); |
extern void interrupts_restore(ipl_t ipl); |
extern ipl_t interrupts_read(void); |
extern void asm_delay_loop(uint32_t t); |
static inline void pio_write_8(ioport8_t *port, uint8_t v) |
{ |
*port = v; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t v) |
{ |
*port = v; |
} |
static inline void pio_write_32(ioport32_t *port, uint32_t v) |
{ |
*port = v; |
} |
static inline uint8_t pio_read_8(ioport8_t *port) |
{ |
return *port; |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
{ |
return *port; |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
{ |
return *port; |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/include/cpu.h |
---|
42,7 → 42,7 |
uint32_t imp_num; |
uint32_t rev_num; |
} cpu_arch_t; |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/include/atomic.h |
---|
35,14 → 35,14 |
#ifndef KERN_mips32_ATOMIC_H_ |
#define KERN_mips32_ATOMIC_H_ |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
#define atomic_inc(x) ((void) atomic_add(x, 1)) |
#define atomic_dec(x) ((void) atomic_add(x, -1)) |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
#define atomic_postinc(x) (atomic_add(x, 1) - 1) |
#define atomic_postdec(x) (atomic_add(x, -1) + 1) |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
#define atomic_preinc(x) atomic_add(x, 1) |
#define atomic_predec(x) atomic_add(x, -1) |
/* Atomic addition of immediate value. |
* |
54,37 → 54,19 |
static inline long atomic_add(atomic_t *val, int i) |
{ |
long tmp, v; |
asm volatile ( |
"1:\n" |
" ll %0, %1\n" |
" addu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
" nop\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "r" (i), "i" (0) |
); |
return v; |
} |
: "=r" (tmp), "=m" (val->count), "=r" (v) |
: "i" (i), "i" (0) |
); |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t tmp, v; |
asm volatile ( |
"1:\n" |
" ll %2, %1\n" |
" bnez %2, 2f\n" |
" li %0, %3\n" |
" sc %0, %1\n" |
" beqz %0, 1b\n" |
"2:\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "i" (1) |
); |
return v; |
} |
/branches/dd/kernel/arch/mips32/include/barrier.h |
---|
45,9 → 45,6 |
#define read_barrier() asm volatile ("" ::: "memory") |
#define write_barrier() asm volatile ("" ::: "memory") |
#define smc_coherence(a) |
#define smc_coherence_block(a, l) |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/include/asm/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
/branches/dd/kernel/arch/mips32/include/console.h |
---|
35,6 → 35,8 |
#ifndef KERN_mips32_CONSOLE_H_ |
#define KERN_mips32_CONSOLE_H_ |
extern void console_init(devno_t devno); |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/include/boot.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_mips32_BOOT_H_ |
#define KERN_mips32_BOOT_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#include <arch/types.h> |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
} utask_t; |
typedef struct { |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
#endif |
/branches/dd/kernel/arch/mips32/include/memstr.h |
---|
37,10 → 37,10 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
extern void memsetw(uintptr_t dst, size_t cnt, uint16_t x); |
extern void memsetb(uintptr_t dst, size_t cnt, uint8_t x); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
extern int memcmp(uintptr_t src, uintptr_t dst, int cnt); |
#endif |
/branches/dd/kernel/arch/mips32/include/arch.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
35,29 → 35,6 |
#ifndef KERN_mips32_ARCH_H_ |
#define KERN_mips32_ARCH_H_ |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#include <typedefs.h> |
extern count_t cpu_count; |
typedef struct { |
uintptr_t addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} utask_t; |
typedef struct { |
uint32_t cpumap; |
uint32_t cnt; |
utask_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
extern void arch_pre_main(void *entry, bootinfo_t *bootinfo); |
#endif |
/** @} |
/branches/dd/kernel/arch/mips32/src/drivers/arc.c |
---|
0,0 → 1,394 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/drivers/arc.h> |
#include <arch/mm/page.h> |
#include <print.h> |
#include <arch.h> |
#include <byteorder.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <interrupt.h> |
#include <align.h> |
#include <console/console.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
#include <mm/slab.h> |
/* This is a good joke, SGI HAS different types than NT bioses... */ |
/* Here is the SGI type */ |
static char *basetypes[] = { |
"ExceptionBlock", |
"SystemParameterBlock", |
"FreeContiguous", |
"FreeMemory", |
"BadMemory", |
"LoadedProgram", |
"FirmwareTemporary", |
"FirmwarePermanent" |
}; |
static char *ctypes[] = { |
"ARC_type", |
"CPU_type", |
"FPU_type", |
"PrimaryICache", |
"PrimaryDCache", |
"SecondaryICache", |
"SecondaryDCache", |
"SecondaryCache", |
"Memory", |
"EISAAdapter", |
"TCAdapter", |
"SCSIAdapter", |
"DTIAdapter", |
"MultiFunctionAdapter", |
"DiskController", |
"TapeController", |
"CDROMController", |
"WORMController", |
"SerialController", |
"NetworkController", |
"DisplayController", |
"ParallelController", |
"PointerController", |
"KeyboardController", |
"AudioController", |
"OtherController", |
"DiskPeripheral", |
"FloppyDiskPeripheral", |
"TapePeripheral", |
"ModemPeripheral", |
"MonitorPeripheral", |
"PrinterPeripheral", |
"PointerPeripheral", |
"KeyboardPeripheral", |
"TerminalPeripheral", |
"OtherPeripheral", |
"LinePeripheral", |
"NetworkPeripheral" |
"OtherPeripheral", |
"XTalkAdapter", |
"PCIAdapter", |
"GIOAdapter", |
"TPUAdapter", |
"Anonymous" |
}; |
static arc_sbp *sbp = (arc_sbp *) PA2KA(0x1000); |
static arc_func_vector_t *arc_entry; |
/** Return true if ARC is available */ |
#define arc_enabled() (sbp != NULL) |
/** Print configuration data that ARC reports about component */ |
static void arc_print_confdata(arc_component *c) |
{ |
cm_resource_list *configdata; |
unsigned int i; |
if (!c->configdatasize) |
return; /* No configuration data */ |
configdata = malloc(c->configdatasize, 0); |
if (arc_entry->getconfigurationdata(configdata, c)) { |
free(configdata); |
return; |
} |
/* Does not seem to return meaningful data, don't use now */ |
free(configdata); |
return; |
for (i = 0; i < configdata->count; i++) { |
switch (configdata->descr[i].type) { |
case CmResourceTypePort: |
printf("Port: %p-size:%d ", |
(uintptr_t) configdata->descr[i].u.port.start, |
configdata->descr[i].u.port.length); |
break; |
case CmResourceTypeInterrupt: |
printf("Irq: level(%d) vector(%d) ", |
configdata->descr[i].u.interrupt.level, |
configdata->descr[i].u.interrupt.vector); |
break; |
case CmResourceTypeMemory: |
printf("Memory: %p-size:%d ", |
(uintptr_t)configdata->descr[i].u.port.start, |
configdata->descr[i].u.port.length); |
break; |
default: |
break; |
} |
} |
free(configdata); |
} |
/** Print information about component */ |
static void arc_print_component(arc_component *c) |
{ |
unsigned int i; |
printf("%s: ",ctypes[c->type]); |
for (i = 0; i < c->identifier_len; i++) |
printf("%c", c->identifier[i]); |
printf(" "); |
arc_print_confdata(c); |
printf("\n"); |
} |
/** |
* Read from ARC bios configuration data and print it |
*/ |
static int cmd_arc_print_devices(cmd_arg_t *argv) |
{ |
arc_component *c, *next; |
c = arc_entry->getchild(NULL); |
while (c) { |
arc_print_component(c); |
next = arc_entry->getchild(c); |
while (!next) { |
next = arc_entry->getpeer(c); |
if (!next) |
c = arc_entry->getparent(c); |
if (!c) |
return 0; |
} |
c = next; |
} |
return 1; |
} |
static cmd_info_t devlist_info = { |
.name = "arcdevlist", |
.description = "Print arc device list", |
.func = cmd_arc_print_devices, |
.argc = 0 |
}; |
/** Read from arc bios memory map and print it |
* |
*/ |
void physmem_print(void) |
{ |
printf("Base Size Type\n"); |
printf("---------- ---------- ---------\n"); |
if (arc_enabled()) { |
arc_memdescriptor_t *desc = arc_entry->getmemorydescriptor(NULL); |
while (desc) { |
printf("%#10x %#10x %s\n", |
desc->basepage * ARC_FRAME, desc->basecount * ARC_FRAME, |
basetypes[desc->type]); |
desc = arc_entry->getmemorydescriptor(desc); |
} |
} else |
printf("%#10x %#10x free\n", 0, CONFIG_MEMORY_SIZE); |
} |
/** Print charactor to console */ |
static void arc_putchar(char ch) |
{ |
uint32_t cnt; |
ipl_t ipl; |
/* TODO: Should be spinlock? */ |
ipl = interrupts_disable(); |
arc_entry->write(1, &ch, 1, &cnt); |
interrupts_restore(ipl); |
} |
/** Initialize ARC structure |
* |
* @return 0 - ARC OK, -1 - ARC does not exist |
*/ |
int arc_init(void) |
{ |
if (sbp->signature != ARC_MAGIC) { |
sbp = NULL; |
return -1; |
} |
arc_entry = sbp->firmwarevector; |
arc_putchar('A'); |
arc_putchar('R'); |
arc_putchar('C'); |
arc_putchar('\n'); |
/* Add command for resetting the computer */ |
cmd_initialize(&devlist_info); |
cmd_register(&devlist_info); |
return 0; |
} |
int arc_reboot(void) |
{ |
if (arc_enabled()) { |
arc_entry->reboot(); |
return true; |
} |
return false; |
} |
static bool kbd_polling_enabled; |
static chardev_t console; |
/** Try to get character, return character or -1 if not available */ |
static void arc_keyboard_poll(void) |
{ |
char ch; |
uint32_t count; |
long result; |
if (!kbd_polling_enabled) |
return; |
if (arc_entry->getreadstatus(0)) |
return; |
result = arc_entry->read(0, &ch, 1, &count); |
if ((result) || (count != 1)) { |
return; |
} |
if (ch == '\r') |
ch = '\n'; |
if (ch == 0x7f) |
ch = '\b'; |
chardev_push_character(&console, ch); |
} |
static char arc_read(chardev_t *dev) |
{ |
char ch; |
uint32_t count; |
long result; |
result = arc_entry->read(0, &ch, 1, &count); |
if ((result) || (count != 1)) { |
printf("Error reading from ARC keyboard.\n"); |
cpu_halt(); |
} |
if (ch == '\r') |
return '\n'; |
if (ch == 0x7f) |
return '\b'; |
return ch; |
} |
static void arc_write(chardev_t *dev, const char ch) |
{ |
arc_putchar(ch); |
} |
static void arc_enable(chardev_t *dev) |
{ |
kbd_polling_enabled = true; |
} |
static void arc_disable(chardev_t *dev) |
{ |
kbd_polling_enabled = false; |
} |
static chardev_operations_t arc_ops = { |
.resume = arc_enable, |
.suspend = arc_disable, |
.write = arc_write, |
.read = arc_read |
}; |
int arc_console(void) |
{ |
if (arc_enabled()) { |
kbd_polling_enabled = true; |
chardev_initialize("arc_console", &console, &arc_ops); |
virtual_timer_fnc = &arc_keyboard_poll; |
stdin = &console; |
stdout = &console; |
return true; |
} |
return false; |
} |
/* Initialize frame zones from ARC firmware. |
* In the future we may use even the FirmwareTemporary regions, |
* currently we use the FreeMemory (what about the LoadedProgram?) |
*/ |
int arc_frame_init(void) |
{ |
if (arc_enabled()) { |
arc_memdescriptor_t *desc; |
uintptr_t base; |
size_t basesize; |
desc = arc_entry->getmemorydescriptor(NULL); |
while (desc) { |
if ((desc->type == FreeMemory) || |
(desc->type == FreeContiguous)) { |
base = desc->basepage*ARC_FRAME; |
basesize = desc->basecount*ARC_FRAME; |
if (base % FRAME_SIZE ) { |
basesize -= FRAME_SIZE - (base % FRAME_SIZE); |
base = ALIGN_UP(base, FRAME_SIZE); |
} |
basesize = ALIGN_DOWN(basesize, FRAME_SIZE); |
zone_create(ADDR2PFN(base), SIZE2FRAMES(basesize), |
ADDR2PFN(base), 0); |
} |
desc = arc_entry->getmemorydescriptor(desc); |
} |
return true; |
} |
return false; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/src/drivers/serial.c |
---|
0,0 → 1,159 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <interrupt.h> |
#include <arch/cp0.h> |
#include <ipc/irq.h> |
#include <arch/drivers/serial.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#define SERIAL_IRQ 2 |
static irq_t serial_irq; |
static chardev_t console; |
static serial_t sconf[SERIAL_MAX]; |
static bool kb_enabled; |
static void serial_write(chardev_t *d, const char ch) |
{ |
serial_t *sd = (serial_t *)d->data; |
if (ch == '\n') |
serial_write(d, '\r'); |
/* Wait until transmit buffer empty */ |
while (! (SERIAL_READ_LSR(sd->port) & (1<<TRANSMIT_EMPTY_BIT))) |
; |
SERIAL_WRITE(sd->port, ch); |
} |
static void serial_enable(chardev_t *d) |
{ |
kb_enabled = true; |
} |
static void serial_disable(chardev_t *d) |
{ |
kb_enabled = false; |
} |
int serial_init(void) |
{ |
int i = 0; |
if (SERIAL_READ_LSR(SERIAL_COM1) == 0x60) { |
sconf[i].port = SERIAL_COM1; |
sconf[i].irq = SERIAL_COM1_IRQ; |
/* Enable interrupt on available data */ |
i++; |
} |
return i; |
} |
/** Read character from serial port, wait until available */ |
static char serial_do_read(chardev_t *dev) |
{ |
serial_t *sd = (serial_t *)dev->data; |
char ch; |
while (!(SERIAL_READ_LSR(sd->port) & 1)) |
; |
ch = SERIAL_READ(sd->port); |
if (ch =='\r') |
ch = '\n'; |
return ch; |
} |
static void serial_handler(void) |
{ |
serial_t *sd = (serial_t *) console.data; |
char ch; |
if (!(SERIAL_READ_LSR(sd->port) & 1)) |
return; |
ch = SERIAL_READ(sd->port); |
if (ch =='\r') |
ch = '\n'; |
chardev_push_character(&console, ch); |
} |
/** Process keyboard interrupt. Does not work in simics? */ |
static void serial_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else |
serial_handler(); |
} |
static irq_ownership_t serial_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static chardev_operations_t serial_ops = { |
.resume = serial_enable, |
.suspend = serial_disable, |
.write = serial_write, |
.read = serial_do_read |
}; |
void serial_console(devno_t devno) |
{ |
serial_t *sd = &sconf[0]; |
chardev_initialize("serial_console", &console, &serial_ops); |
console.data = sd; |
kb_enabled = true; |
irq_initialize(&serial_irq); |
serial_irq.devno = devno; |
serial_irq.inr = SERIAL_IRQ; |
serial_irq.claim = serial_claim; |
serial_irq.handler = serial_irq_handler; |
irq_register(&serial_irq); |
/* I don't know why, but the serial interrupts simply |
* don't work on simics |
*/ |
virtual_timer_fnc = &serial_handler; |
stdin = &console; |
stdout = &console; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/src/drivers/msim.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
33,17 → 33,22 |
*/ |
#include <interrupt.h> |
#include <ipc/irq.h> |
#include <console/chardev.h> |
#include <arch/drivers/msim.h> |
#include <arch/cp0.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/** Address of devices. */ |
#define MSIM_VIDEORAM 0xB0000000 |
#define MSIM_KBD_ADDRESS 0xB0000000 |
#define MSIM_KBD_IRQ 2 |
static chardev_t console; |
static irq_t msim_irq; |
static void msim_write(chardev_t *dev, const char ch, bool silent); |
static void msim_write(chardev_t *dev, const char ch); |
static void msim_enable(chardev_t *dev); |
static void msim_disable(chardev_t *dev); |
static char msim_do_read(chardev_t *dev); |
56,10 → 61,9 |
}; |
/** Putchar that works with MSIM & gxemul */ |
void msim_write(chardev_t *dev, const char ch, bool silent) |
void msim_write(chardev_t *dev, const char ch) |
{ |
if (!silent) |
*((char *) MSIM_VIDEORAM) = ch; |
*((char *) MSIM_VIDEORAM) = ch; |
} |
/* Called from getc(). */ |
74,11 → 78,12 |
cp0_mask_int(MSIM_KBD_IRQ); |
} |
#include <print.h> |
/** Read character using polling, assume interrupts disabled */ |
static char msim_do_read(chardev_t *dev) |
{ |
char ch; |
while (1) { |
ch = *((volatile char *) MSIM_KBD_ADDRESS); |
if (ch) { |
92,19 → 97,23 |
} |
/** Process keyboard interrupt. */ |
static void msim_irq_handler(irq_t *irq) |
static void msim_irq_handler(irq_t *irq, void *arg, ...) |
{ |
char ch = 0; |
if ((irq->notif_cfg.notify) && (irq->notif_cfg.answerbox)) |
ipc_irq_send_notif(irq); |
else { |
char ch = 0; |
ch = *((char *) MSIM_KBD_ADDRESS); |
if (ch =='\r') |
ch = '\n'; |
if (ch == 0x7f) |
ch = '\b'; |
chardev_push_character(&console, ch); |
ch = *((char *) MSIM_KBD_ADDRESS); |
if (ch =='\r') |
ch = '\n'; |
if (ch == 0x7f) |
ch = '\b'; |
chardev_push_character(&console, ch); |
} |
} |
static irq_ownership_t msim_claim(irq_t *irq) |
static irq_ownership_t msim_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
149,10 → 158,6 |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, MSIM_KBD_IRQ); |
sysinfo_set_item_val("kbd.address.virtual", NULL, MSIM_KBD_ADDRESS); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 3); |
sysinfo_set_item_val("fb.address.physical", NULL, KA2PA(MSIM_VIDEORAM)); |
} |
/** @} |
/branches/dd/kernel/arch/mips32/src/cpu/cpu.c |
---|
48,7 → 48,7 |
{ "MIPS", "R2000" }, /* 0x01 */ |
{ "MIPS", "R3000" }, /* 0x02 */ |
{ "MIPS", "R6000" }, /* 0x03 */ |
{ "MIPS", "R4000/R4400" }, /* 0x04 */ |
{ "MIPS", " R4000/R4400" }, /* 0x04 */ |
{ "LSI Logic", "R3000" }, /* 0x05 */ |
{ "MIPS", "R6000A" }, /* 0x06 */ |
{ "IDT", "3051/3052" }, /* 0x07 */ |
123,9 → 123,9 |
data = &imp_data[m->arch.imp_num]; |
} |
printf("cpu%u: %s %s (rev=%d.%d, imp=%d)\n", |
printf("cpu%d: %s %s (rev=%d.%d, imp=%d)\n", |
m->id, data->vendor, data->model, m->arch.rev_num >> 4, |
m->arch.rev_num & 0x0f, m->arch.imp_num); |
m->arch.rev_num & 0xf, m->arch.imp_num); |
} |
/** @} |
/branches/dd/kernel/arch/mips32/src/debugger.c |
---|
33,7 → 33,6 |
*/ |
#include <arch/debugger.h> |
#include <arch/barrier.h> |
#include <memstr.h> |
#include <console/kconsole.h> |
#include <console/cmd.h> |
47,8 → 46,6 |
bpinfo_t breakpoints[BKPOINTS_MAX]; |
SPINLOCK_INITIALIZE(bkpoint_lock); |
#ifdef CONFIG_KCONSOLE |
static int cmd_print_breakpoints(cmd_arg_t *argv); |
static cmd_info_t bkpts_info = { |
.name = "bkpts", |
75,8 → 72,7 |
}; |
static cmd_info_t addbkpt_info = { |
.name = "addbkpt", |
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch " |
"insts unsupported.", |
.description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch insts unsupported.", |
.func = cmd_add_breakpoint, |
.argc = 1, |
.argv = &add_argv |
88,8 → 84,7 |
}; |
static cmd_info_t addbkpte_info = { |
.name = "addbkpte", |
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call " |
"func(or Nothing if 0).", |
.description = "addebkpte <&symbol> <&func> - new bkpoint. Call func(or Nothing if 0).", |
.func = cmd_add_breakpoint, |
.argc = 2, |
.argv = adde_argv |
98,7 → 93,7 |
static struct { |
uint32_t andmask; |
uint32_t value; |
} jmpinstr[] = { |
}jmpinstr[] = { |
{0xf3ff0000, 0x41000000}, /* BCzF */ |
{0xf3ff0000, 0x41020000}, /* BCzFL */ |
{0xf3ff0000, 0x41010000}, /* BCzT */ |
122,21 → 117,19 |
{0xfc000000, 0x08000000}, /* J */ |
{0xfc000000, 0x0c000000}, /* JAL */ |
{0xfc1f07ff, 0x00000009}, /* JALR */ |
{0, 0} /* EndOfTable */ |
{0,0} /* EndOfTable */ |
}; |
/** Test, if the given instruction is a jump or branch instruction |
* |
* @param instr Instruction code |
* @return true - it is jump instruction, false otherwise |
* |
*/ |
static bool is_jump(unative_t instr) |
{ |
int i; |
for (i = 0; jmpinstr[i].andmask; i++) { |
for (i=0;jmpinstr[i].andmask;i++) { |
if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value) |
return true; |
} |
159,23 → 152,21 |
spinlock_lock(&bkpoint_lock); |
/* Check, that the breakpoints do not conflict */ |
for (i = 0; i < BKPOINTS_MAX; i++) { |
for (i=0; i<BKPOINTS_MAX; i++) { |
if (breakpoints[i].address == (uintptr_t)argv->intval) { |
printf("Duplicate breakpoint %d.\n", i); |
spinlock_unlock(&bkpoint_lock); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + |
sizeof(unative_t) || breakpoints[i].address == |
(uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict " |
"with %d.\n", i); |
spinlock_unlock(&bkpoint_lock); |
} else if (breakpoints[i].address == (uintptr_t)argv->intval + sizeof(unative_t) || \ |
breakpoints[i].address == (uintptr_t)argv->intval - sizeof(unative_t)) { |
printf("Adjacent breakpoints not supported, conflict with %d.\n", i); |
spinlock_unlock(&bkpoints_lock); |
return 0; |
} |
} |
for (i = 0; i < BKPOINTS_MAX; i++) |
for (i=0; i<BKPOINTS_MAX; i++) |
if (!breakpoints[i].address) { |
cur = &breakpoints[i]; |
break; |
194,7 → 185,7 |
cur->flags = 0; |
} else { /* We are add extended */ |
cur->flags = BKPOINT_FUNCCALL; |
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; |
cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; |
} |
if (is_jump(cur->instruction)) |
cur->flags |= BKPOINT_ONESHOT; |
202,7 → 193,6 |
/* Set breakpoint */ |
*((unative_t *)cur->address) = 0x0d; |
smc_coherence(cur->address); |
spinlock_unlock(&bkpoint_lock); |
interrupts_restore(ipl); |
210,6 → 200,8 |
return 1; |
} |
/** Remove breakpoint from table */ |
int cmd_del_breakpoint(cmd_arg_t *argv) |
{ |
237,9 → 229,7 |
return 0; |
} |
((uint32_t *)cur->address)[0] = cur->instruction; |
smc_coherence(((uint32_t *)cur->address)[0]); |
((uint32_t *)cur->address)[1] = cur->nextinstruction; |
smc_coherence(((uint32_t *)cur->address)[1]); |
cur->address = NULL; |
262,42 → 252,38 |
symbol = get_symtab_entry(breakpoints[i].address); |
printf("%-2u %-5d %#10zx %-6s %-7s %-8s %s\n", i, |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : |
"false"), ((breakpoints[i].flags & BKPOINT_ONESHOT) |
? "true" : "false"), ((breakpoints[i].flags & |
BKPOINT_FUNCCALL) ? "true" : "false"), symbol); |
breakpoints[i].counter, breakpoints[i].address, |
((breakpoints[i].flags & BKPOINT_INPROG) ? "true" : "false"), |
((breakpoints[i].flags & BKPOINT_ONESHOT) ? "true" : "false"), |
((breakpoints[i].flags & BKPOINT_FUNCCALL) ? "true" : "false"), |
symbol); |
} |
return 1; |
} |
#endif |
/** Initialize debugger */ |
void debugger_init() |
{ |
int i; |
for (i = 0; i < BKPOINTS_MAX; i++) |
for (i=0; i<BKPOINTS_MAX; i++) |
breakpoints[i].address = NULL; |
#ifdef CONFIG_KCONSOLE |
cmd_initialize(&bkpts_info); |
if (!cmd_register(&bkpts_info)) |
printf("Cannot register command %s\n", bkpts_info.name); |
panic("could not register command %s\n", bkpts_info.name); |
cmd_initialize(&delbkpt_info); |
if (!cmd_register(&delbkpt_info)) |
printf("Cannot register command %s\n", delbkpt_info.name); |
panic("could not register command %s\n", delbkpt_info.name); |
cmd_initialize(&addbkpt_info); |
if (!cmd_register(&addbkpt_info)) |
printf("Cannot register command %s\n", addbkpt_info.name); |
panic("could not register command %s\n", addbkpt_info.name); |
cmd_initialize(&addbkpte_info); |
if (!cmd_register(&addbkpte_info)) |
printf("Cannot register command %s\n", addbkpte_info.name); |
#endif |
panic("could not register command %s\n", addbkpte_info.name); |
} |
/** Handle breakpoint |
316,19 → 302,19 |
/* test branch delay slot */ |
if (cp0_cause_read() & 0x80000000) |
panic("Breakpoint in branch delay slot not supported."); |
panic("Breakpoint in branch delay slot not supported.\n"); |
spinlock_lock(&bkpoint_lock); |
for (i = 0; i < BKPOINTS_MAX; i++) { |
for (i=0; i<BKPOINTS_MAX; i++) { |
/* Normal breakpoint */ |
if (fireaddr == breakpoints[i].address && |
!(breakpoints[i].flags & BKPOINT_REINST)) { |
if (fireaddr == breakpoints[i].address \ |
&& !(breakpoints[i].flags & BKPOINT_REINST)) { |
cur = &breakpoints[i]; |
break; |
} |
/* Reinst only breakpoint */ |
if ((breakpoints[i].flags & BKPOINT_REINST) && |
(fireaddr == breakpoints[i].address + sizeof(unative_t))) { |
if ((breakpoints[i].flags & BKPOINT_REINST) \ |
&& (fireaddr ==breakpoints[i].address+sizeof(unative_t))) { |
cur = &breakpoints[i]; |
break; |
} |
337,10 → 323,8 |
if (cur->flags & BKPOINT_REINST) { |
/* Set breakpoint on first instruction */ |
((uint32_t *)cur->address)[0] = 0x0d; |
smc_coherence(((uint32_t *)cur->address)[0]); |
/* Return back the second */ |
((uint32_t *)cur->address)[1] = cur->nextinstruction; |
smc_coherence(((uint32_t *)cur->address)[1]); |
cur->flags &= ~BKPOINT_REINST; |
spinlock_unlock(&bkpoint_lock); |
return; |
349,12 → 333,11 |
printf("Warning: breakpoint recursion\n"); |
if (!(cur->flags & BKPOINT_FUNCCALL)) |
printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, |
get_symtab_entry(istate->epc)); |
printf("***Breakpoint %d: %p in %s.\n", i, |
fireaddr, get_symtab_entry(istate->epc)); |
/* Return first instruction back */ |
((uint32_t *)cur->address)[0] = cur->instruction; |
smc_coherence(cur->address); |
if (! (cur->flags & BKPOINT_ONESHOT)) { |
/* Set Breakpoint on next instruction */ |
375,20 → 358,19 |
if (cur->bkfunc) |
cur->bkfunc(cur, istate); |
} else { |
#ifdef CONFIG_KCONSOLE |
printf("***Type 'exit' to exit kconsole.\n"); |
/* This disables all other processors - we are not SMP, |
* actually this gets us to cpu_halt, if scheduler() is run |
* - we generally do not want scheduler to be run from debug, |
* so this is a good idea |
*/ |
atomic_set(&haltstate, 1); |
atomic_set(&haltstate,1); |
spinlock_unlock(&bkpoint_lock); |
kconsole("debug", "Debug console ready (type 'exit' to continue)\n", false); |
kconsole("debug"); |
spinlock_lock(&bkpoint_lock); |
atomic_set(&haltstate, 0); |
#endif |
atomic_set(&haltstate,0); |
} |
if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { |
/* Remove one-shot breakpoint */ |
/branches/dd/kernel/arch/mips32/src/mm/tlb.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
41,20 → 41,24 |
#include <panic.h> |
#include <arch.h> |
#include <symtab.h> |
#include <synch/mutex.h> |
#include <synch/spinlock.h> |
#include <print.h> |
#include <debug.h> |
#include <align.h> |
#include <interrupt.h> |
static void tlb_refill_fail(istate_t *); |
static void tlb_invalid_fail(istate_t *); |
static void tlb_modified_fail(istate_t *); |
static void tlb_refill_fail(istate_t *istate); |
static void tlb_invalid_fail(istate_t *istate); |
static void tlb_modified_fail(istate_t *istate); |
static pte_t *find_mapping_and_check(uintptr_t, int, istate_t *, int *); |
static pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc); |
/** Initialize TLB. |
static void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn); |
static void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr); |
/** Initialize TLB |
* |
* Initialize TLB. |
* Invalidate all entries and mark wired entries. |
*/ |
void tlb_arch_init(void) |
72,6 → 76,7 |
cp0_index_write(i); |
tlbwi(); |
} |
/* |
* The kernel is going to make use of some wired |
80,9 → 85,11 |
cp0_wired_write(TLB_WIRED); |
} |
/** Process TLB Refill Exception. |
/** Process TLB Refill Exception |
* |
* @param istate Interrupted register context. |
* Process TLB Refill Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_refill(istate_t *istate) |
{ |
92,15 → 99,15 |
uintptr_t badvaddr; |
pte_t *pte; |
int pfrc; |
badvaddr = cp0_badvaddr_read(); |
mutex_lock(&AS->lock); |
spinlock_lock(&AS->lock); |
asid = AS->asid; |
mutex_unlock(&AS->lock); |
spinlock_unlock(&AS->lock); |
page_table_lock(AS, true); |
pte = find_mapping_and_check(badvaddr, PF_ACCESS_READ, istate, &pfrc); |
if (!pte) { |
switch (pfrc) { |
115,7 → 122,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
124,15 → 131,14 |
*/ |
pte->a = 1; |
tlb_prepare_entry_hi(&hi, asid, badvaddr); |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
prepare_entry_hi(&hi, asid, badvaddr); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
/* |
* New entry is to be inserted into TLB |
*/ |
cp0_entry_hi_write(hi.value); |
if ((badvaddr / PAGE_SIZE) % 2 == 0) { |
if ((badvaddr/PAGE_SIZE) % 2 == 0) { |
cp0_entry_lo0_write(lo.value); |
cp0_entry_lo1_write(0); |
} |
151,9 → 157,11 |
tlb_refill_fail(istate); |
} |
/** Process TLB Invalid Exception. |
/** Process TLB Invalid Exception |
* |
* @param istate Interrupted register context. |
* Process TLB Invalid Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_invalid(istate_t *istate) |
{ |
170,7 → 178,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
199,7 → 207,7 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
213,13 → 221,12 |
*/ |
pte->a = 1; |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, |
pte->pfn); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->d, pte->cacheable, pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
234,9 → 241,11 |
tlb_invalid_fail(istate); |
} |
/** Process TLB Modified Exception. |
/** Process TLB Modified Exception |
* |
* @param istate Interrupted register context. |
* Process TLB Modified Exception. |
* |
* @param istate Interrupted register context. |
*/ |
void tlb_modified(istate_t *istate) |
{ |
253,7 → 262,7 |
* Locate the faulting entry in TLB. |
*/ |
hi.value = cp0_entry_hi_read(); |
tlb_prepare_entry_hi(&hi, hi.asid, badvaddr); |
prepare_entry_hi(&hi, hi.asid, badvaddr); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
index.value = cp0_index_read(); |
282,11 → 291,17 |
page_table_unlock(AS, true); |
return; |
default: |
panic("Unexpected pfrc (%d).", pfrc); |
panic("unexpected pfrc (%d)\n", pfrc); |
} |
} |
/* |
* Fail if the page is not writable. |
*/ |
if (!pte->w) |
goto fail; |
/* |
* Read the faulting TLB entry. |
*/ |
tlbr(); |
297,13 → 312,12 |
pte->a = 1; |
pte->d = 1; |
tlb_prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, |
pte->pfn); |
prepare_entry_lo(&lo, pte->g, pte->p, pte->w, pte->cacheable, pte->pfn); |
/* |
* The entry is to be updated in TLB. |
*/ |
if ((badvaddr / PAGE_SIZE) % 2 == 0) |
if ((badvaddr/PAGE_SIZE) % 2 == 0) |
cp0_entry_lo0_write(lo.value); |
else |
cp0_entry_lo1_write(lo.value); |
330,10 → 344,8 |
if (s) |
sym2 = s; |
fault_if_from_uspace(istate, "TLB Refill Exception on %p.", |
cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s).", cp0_badvaddr_read(), |
istate->epc, symbol, sym2); |
fault_if_from_uspace(istate, "TLB Refill Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Refill Exception at %x(%s<-%s)\n", cp0_badvaddr_read(), istate->epc, symbol, sym2); |
} |
344,10 → 356,8 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p.", |
cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s).", cp0_badvaddr_read(), |
istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Invalid Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Invalid Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
} |
void tlb_modified_fail(istate_t *istate) |
357,27 → 367,23 |
char *s = get_symtab_entry(istate->epc); |
if (s) |
symbol = s; |
fault_if_from_uspace(istate, "TLB Modified Exception on %p.", |
cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s).", cp0_badvaddr_read(), |
istate->epc, symbol); |
fault_if_from_uspace(istate, "TLB Modified Exception on %p", cp0_badvaddr_read()); |
panic("%x: TLB Modified Exception at %x(%s)\n", cp0_badvaddr_read(), istate->epc, symbol); |
} |
/** Try to find PTE for faulting address. |
/** Try to find PTE for faulting address |
* |
* Try to find PTE for faulting address. |
* The AS->lock must be held on entry to this function. |
* |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code |
* will be stored. |
* @param badvaddr Faulting virtual address. |
* @param access Access mode that caused the fault. |
* @param istate Pointer to interrupted state. |
* @param pfrc Pointer to variable where as_page_fault() return code will be stored. |
* |
* @return PTE on success, NULL otherwise. |
* @return PTE on success, NULL otherwise. |
*/ |
pte_t * |
find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, |
int *pfrc) |
pte_t *find_mapping_and_check(uintptr_t badvaddr, int access, istate_t *istate, int *pfrc) |
{ |
entry_hi_t hi; |
pte_t *pte; |
396,7 → 402,7 |
* Check if the mapping exists in page tables. |
*/ |
pte = page_mapping_find(AS, badvaddr); |
if (pte && pte->p && (pte->w || access != PF_ACCESS_WRITE)) { |
if (pte && pte->p) { |
/* |
* Mapping found in page tables. |
* Immediately succeed. |
419,7 → 425,6 |
page_table_lock(AS, true); |
pte = page_mapping_find(AS, badvaddr); |
ASSERT(pte && pte->p); |
ASSERT(pte->w || access != PF_ACCESS_WRITE); |
return pte; |
break; |
case AS_PF_DEFER: |
429,19 → 434,18 |
break; |
case AS_PF_FAULT: |
page_table_lock(AS, true); |
printf("Page fault.\n"); |
*pfrc = AS_PF_FAULT; |
return NULL; |
break; |
default: |
panic("Unexpected rc (%d).", rc); |
panic("unexpected rc (%d)\n", rc); |
} |
} |
} |
void |
tlb_prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, |
uintptr_t pfn) |
void prepare_entry_lo(entry_lo_t *lo, bool g, bool v, bool d, bool cacheable, uintptr_t pfn) |
{ |
lo->value = 0; |
lo->g = g; |
451,7 → 455,7 |
lo->pfn = pfn; |
} |
void tlb_prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
void prepare_entry_hi(entry_hi_t *hi, asid_t asid, uintptr_t addr) |
{ |
hi->value = ALIGN_DOWN(addr, PAGE_SIZE * 2); |
hi->asid = asid; |
480,10 → 484,10 |
lo1.value = cp0_entry_lo1_read(); |
printf("%-2u %-4u %#6x %#4x %1u %1u %1u %1u %#6x\n", |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
i, hi.asid, hi.vpn2, mask.mask, |
lo0.g, lo0.v, lo0.d, lo0.c, lo0.pfn); |
printf(" %1u %1u %1u %1u %#6x\n", |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
lo1.g, lo1.v, lo1.d, lo1.c, lo1.pfn); |
} |
cp0_entry_hi_write(hi_save.value); |
560,12 → 564,11 |
cp0_entry_hi_write(hi_save.value); |
} |
/** Invalidate TLB entries for specified page range belonging to specified |
* address space. |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
* @param asid Address space identifier. |
* @param page First page whose TLB entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
582,7 → 585,7 |
for (i = 0; i < cnt + 1; i += 2) { |
hi.value = 0; |
tlb_prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
prepare_entry_hi(&hi, asid, page + i * PAGE_SIZE); |
cp0_entry_hi_write(hi.value); |
tlbp(); |
589,10 → 592,7 |
index.value = cp0_index_read(); |
if (!index.p) { |
/* |
* Entry was found, index register contains valid |
* index. |
*/ |
/* Entry was found, index register contains valid index. */ |
tlbr(); |
lo0.value = cp0_entry_lo0_read(); |
/branches/dd/kernel/arch/mips32/src/mm/frame.c |
---|
26,244 → 26,33 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
*/ |
#include <macros.h> |
#include <arch/mm/frame.h> |
#include <arch/mm/tlb.h> |
#include <interrupt.h> |
#include <mm/frame.h> |
#include <mm/asid.h> |
#include <config.h> |
#include <arch/drivers/msim.h> |
#include <arch/drivers/serial.h> |
#include <print.h> |
#include <arch/drivers/arc.h> |
#define ZERO_PAGE_MASK TLB_PAGE_MASK_256K |
#define ZERO_FRAMES 2048 |
#define ZERO_PAGE_WIDTH 18 /* 256K */ |
#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH) |
#define ZERO_PAGE_ASID ASID_INVALID |
#define ZERO_PAGE_TLBI 0 |
#define ZERO_PAGE_ADDR 0 |
#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1) |
#define ZERO_PAGE_VALUE (((volatile uint32_t *) ZERO_PAGE_ADDR)[ZERO_PAGE_OFFSET]) |
#define ZERO_PAGE_VALUE_KSEG1(frame) (((volatile uint32_t *) (0xa0000000 + (frame << ZERO_PAGE_WIDTH)))[ZERO_PAGE_OFFSET]) |
#define MAX_REGIONS 32 |
typedef struct { |
pfn_t start; |
pfn_t count; |
} phys_region_t; |
static count_t phys_regions_count = 0; |
static phys_region_t phys_regions[MAX_REGIONS]; |
/** Check whether frame is available |
* |
* Returns true if given frame is generally available for use. |
* Returns false if given frame is used for physical memory |
* mapped devices and cannot be used. |
* |
*/ |
static bool frame_available(pfn_t frame) |
{ |
#ifdef MACHINE_msim |
/* MSIM device (dprinter) */ |
if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH)) |
return false; |
/* MSIM device (dkeyboard) */ |
if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#ifdef MACHINE_simics |
/* Simics device (serial line) */ |
if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH)) |
return false; |
#endif |
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) |
/* gxemul devices */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
0x10000000, MB2SIZE(256))) |
return false; |
#endif |
return true; |
} |
/** Check whether frame is safe to write |
* |
* Returns true if given frame is safe for read/write test. |
* Returns false if given frame should not be touched. |
* |
*/ |
static bool frame_safe(pfn_t frame) |
{ |
/* Kernel structures */ |
if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base)) |
return false; |
/* Kernel */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.base), config.kernel_size)) |
return false; |
/* Kernel stack */ |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(config.stack_base), config.stack_size)) |
return false; |
/* Init tasks */ |
bool safe = true; |
count_t i; |
for (i = 0; i < init.cnt; i++) |
if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE, |
KA2PA(init.tasks[i].addr), init.tasks[i].size)) { |
safe = false; |
break; |
} |
return safe; |
} |
static void frame_add_region(pfn_t start_frame, pfn_t end_frame) |
{ |
if (end_frame > start_frame) { |
/* Convert 1M frames to 16K frames */ |
pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH); |
pfn_t count = ADDR2PFN((end_frame - start_frame) << ZERO_PAGE_WIDTH); |
/* Interrupt vector frame is blacklisted */ |
pfn_t conf_frame; |
if (first == 0) |
conf_frame = 1; |
else |
conf_frame = first; |
zone_create(first, count, conf_frame, 0); |
if (phys_regions_count < MAX_REGIONS) { |
phys_regions[phys_regions_count].start = first; |
phys_regions[phys_regions_count].count = count; |
phys_regions_count++; |
} |
} |
} |
/** Create memory zones |
* |
* Walk through available 256 KB chunks of physical |
* memory and create zones. |
* |
* Note: It is assumed that the TLB is not yet being |
* used in any way, thus there is no interference. |
* |
* If ARC is known, read information from ARC, otherwise |
* assume some defaults. |
* - blacklist first FRAME because there is an exception vector |
*/ |
void frame_arch_init(void) |
{ |
ipl_t ipl = interrupts_disable(); |
/* Clear and initialize TLB */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
count_t i; |
for (i = 0; i < TLB_ENTRY_COUNT; i++) { |
cp0_index_write(i); |
tlbwi(); |
if (!arc_frame_init()) { |
zone_create(0, ADDR2PFN(CONFIG_MEMORY_SIZE), 1, 0); |
/* |
* Blacklist interrupt vector |
*/ |
frame_mark_unavailable(0, 1); |
} |
pfn_t start_frame = 0; |
pfn_t frame; |
bool avail = true; |
/* Walk through all 1 MB frames */ |
for (frame = 0; frame < ZERO_FRAMES; frame++) { |
if (!frame_available(frame)) |
avail = false; |
else { |
if (frame_safe(frame)) { |
entry_lo_t lo0; |
entry_lo_t lo1; |
entry_hi_t hi; |
tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12)); |
tlb_prepare_entry_lo(&lo1, false, false, false, false, 0); |
tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR); |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(lo0.value); |
cp0_entry_lo1_write(lo1.value); |
cp0_entry_hi_write(hi.value); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
ZERO_PAGE_VALUE = 0; |
if (ZERO_PAGE_VALUE != 0) |
avail = false; |
else { |
ZERO_PAGE_VALUE = 0xdeadbeef; |
if (ZERO_PAGE_VALUE != 0xdeadbeef) |
avail = false; |
#if defined(MACHINE_lgxemul) || defined(MACHINE_bgxemul) |
else { |
ZERO_PAGE_VALUE_KSEG1(frame) = 0xaabbccdd; |
if (ZERO_PAGE_VALUE_KSEG1(frame) != 0xaabbccdd) |
avail = false; |
} |
#endif |
} |
} |
} |
if (!avail) { |
frame_add_region(start_frame, frame); |
start_frame = frame + 1; |
avail = true; |
} |
} |
frame_add_region(start_frame, frame); |
/* Blacklist interrupt vector frame */ |
frame_mark_unavailable(0, 1); |
/* Cleanup */ |
cp0_pagemask_write(ZERO_PAGE_MASK); |
cp0_entry_lo0_write(0); |
cp0_entry_lo1_write(0); |
cp0_entry_hi_write(0); |
cp0_index_write(ZERO_PAGE_TLBI); |
tlbwi(); |
interrupts_restore(ipl); |
} |
void physmem_print(void) |
{ |
printf("Base Size\n"); |
printf("---------- ----------\n"); |
count_t i; |
for (i = 0; i < phys_regions_count; i++) { |
printf("%#010x %10u\n", |
PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count)); |
} |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/src/mm/as.c |
---|
44,7 → 44,7 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
as_operations = &as_pt_operations; |
asid_fifo_init(); |
} |
/branches/dd/kernel/arch/mips32/src/mm/page.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32mm |
/** @addtogroup mips32mm |
* @{ |
*/ |
/** @file |
35,7 → 35,6 |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <mm/page.h> |
#include <mm/frame.h> |
void page_arch_init(void) |
{ |
/branches/dd/kernel/arch/mips32/src/console.c |
---|
34,18 → 34,25 |
#include <console/console.h> |
#include <arch/console.h> |
#include <arch/drivers/arc.h> |
#include <arch/drivers/serial.h> |
#include <arch/drivers/msim.h> |
#include <genarch/fb/fb.h> |
void console_init(devno_t devno) |
{ |
if (!arc_console()) { |
if (serial_init()) |
serial_console(devno); |
else |
msim_console(devno); |
} |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
fb_redraw(); |
#endif |
msim_kbd_grab(); |
} |
/branches/dd/kernel/arch/mips32/src/mips32.c |
---|
33,6 → 33,7 |
*/ |
#include <arch.h> |
#include <arch/boot.h> |
#include <arch/cp0.h> |
#include <arch/exception.h> |
#include <mm/as.h> |
47,55 → 48,44 |
#include <sysinfo/sysinfo.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/arc.h> |
#include <console/chardev.h> |
#include <arch/barrier.h> |
#include <arch/debugger.h> |
#include <genarch/fb/fb.h> |
#include <genarch/fb/visuals.h> |
#include <macros.h> |
#include <ddi/device.h> |
#include <config.h> |
#include <string.h> |
#include <arch/drivers/msim.h> |
#include <arch/asm/regname.h> |
/* Size of the code jumping to the exception handler code |
* - J+NOP |
/* Size of the code jumping to the exception handler code |
* - J+NOP |
*/ |
#define EXCEPTION_JUMP_SIZE 8 |
#define EXCEPTION_JUMP_SIZE 8 |
#define TLB_EXC ((char *) 0x80000000) |
#define NORM_EXC ((char *) 0x80000180) |
#define CACHE_EXC ((char *) 0x80000100) |
#define TLB_EXC ((char *) 0x80000000) |
#define NORM_EXC ((char *) 0x80000180) |
#define CACHE_EXC ((char *) 0x80000100) |
/* Why the linker moves the variable 64K away in assembler |
* when not in .text section? |
* when not in .text section ???????? |
*/ |
uintptr_t supervisor_sp __attribute__ ((section (".text"))); |
/* Stack pointer saved when entering user mode */ |
uintptr_t supervisor_sp __attribute__ ((section (".text"))); |
/* TODO: How do we do it on SMP system???? */ |
bootinfo_t bootinfo __attribute__ ((section (".text"))); |
count_t cpu_count = 0; |
/** Performs mips32-specific initialization before main_bsp() is called. */ |
void arch_pre_main(void *entry __attribute__((unused)), bootinfo_t *bootinfo) |
void arch_pre_main(void) |
{ |
/* Setup usermode */ |
init.cnt = bootinfo->cnt; |
init.cnt = bootinfo.cnt; |
count_t i; |
for (i = 0; i < min3(bootinfo->cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); i++) { |
init.tasks[i].addr = bootinfo->tasks[i].addr; |
init.tasks[i].size = bootinfo->tasks[i].size; |
strncpy(init.tasks[i].name, bootinfo->tasks[i].name, |
CONFIG_TASK_NAME_BUFLEN); |
} |
uint32_t i; |
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { |
if ((bootinfo->cpumap & (1 << i)) != 0) |
cpu_count++; |
for (i = 0; i < bootinfo.cnt; i++) { |
init.tasks[i].addr = bootinfo.tasks[i].addr; |
init.tasks[i].size = bootinfo.tasks[i].size; |
} |
} |
106,27 → 96,24 |
/* Initialize dispatch table */ |
exception_init(); |
arc_init(); |
/* Copy the exception vectors to the right places */ |
memcpy(TLB_EXC, (char *) tlb_refill_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(TLB_EXC, EXCEPTION_JUMP_SIZE); |
memcpy(NORM_EXC, (char *) exception_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(NORM_EXC, EXCEPTION_JUMP_SIZE); |
memcpy(CACHE_EXC, (char *) cache_error_entry, EXCEPTION_JUMP_SIZE); |
smc_coherence_block(CACHE_EXC, EXCEPTION_JUMP_SIZE); |
/* |
* Switch to BEV normal level so that exception vectors point to the |
* kernel. Clear the error level. |
* Switch to BEV normal level so that exception vectors point to the kernel. |
* Clear the error level. |
*/ |
cp0_status_write(cp0_status_read() & |
~(cp0_status_bev_bootstrap_bit | cp0_status_erl_error_bit)); |
/* |
* Mask all interrupts |
cp0_status_write(cp0_status_read() & ~(cp0_status_bev_bootstrap_bit|cp0_status_erl_error_bit)); |
/* |
* Mask all interrupts |
*/ |
cp0_mask_all_int(); |
debugger_init(); |
} |
133,35 → 120,11 |
void arch_post_mm_init(void) |
{ |
interrupt_init(); |
msim_console(device_assign_devno()); |
console_init(device_assign_devno()); |
#ifdef CONFIG_FB |
/* GXemul framebuffer */ |
fb_properties_t gxemul_prop = { |
.addr = 0x12000000, |
.offset = 0, |
.x = 640, |
.y = 480, |
.scan = 1920, |
.visual = VISUAL_BGR_8_8_8, |
}; |
fb_init(&gxemul_prop); |
fb_init(0x12000000, 640, 480, 1920, VISUAL_RGB_8_8_8); // gxemul framebuffer |
#endif |
#ifdef MACHINE_msim |
sysinfo_set_item_val("machine.msim", NULL, 1); |
#endif |
#ifdef MACHINE_simics |
sysinfo_set_item_val("machine.simics", NULL, 1); |
#endif |
#ifdef MACHINE_bgxemul |
sysinfo_set_item_val("machine.bgxemul", NULL, 1); |
#endif |
#ifdef MACHINE_lgxemul |
sysinfo_set_item_val("machine.lgxemul", NULL, 1); |
#endif |
sysinfo_set_item_val("machine." STRING(MACHINE), NULL, 1); |
} |
void arch_post_cpu_init(void) |
176,19 → 139,15 |
{ |
} |
void calibrate_delay_loop(void) |
{ |
} |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
/* EXL = 1, UM = 1, IE = 1 */ |
cp0_status_write(cp0_status_read() | (cp0_status_exl_exception_bit | |
cp0_status_um_bit | cp0_status_ie_enabled_bit)); |
cp0_status_um_bit | cp0_status_ie_enabled_bit)); |
cp0_epc_write((uintptr_t) kernel_uarg->uspace_entry); |
userspace_asm(((uintptr_t) kernel_uarg->uspace_stack + PAGE_SIZE), |
(uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_entry); |
(uintptr_t) kernel_uarg->uspace_uarg, |
(uintptr_t) kernel_uarg->uspace_entry); |
while (1); |
} |
201,8 → 160,7 |
/** Perform mips32 specific tasks needed before the new thread is scheduled. */ |
void before_thread_runs_arch(void) |
{ |
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
supervisor_sp = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
} |
void after_thread_ran_arch(void) |
221,24 → 179,11 |
void arch_reboot(void) |
{ |
___halt(); |
if (!arc_reboot()) |
___halt(); |
while (1); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/src/smp/dorder.c |
---|
File deleted |
/branches/dd/kernel/arch/mips32/src/smp/smp.c |
---|
File deleted |
/branches/dd/kernel/arch/mips32/src/smp/order.c |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2007 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup mips32 |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/smp/order.h> |
#define MSIM_ORDER_ADDRESS 0xB0000004 |
void ipi_broadcast_arch(int ipi) |
{ |
*((volatile unsigned int *) MSIM_ORDER_ADDRESS) = 0x7FFFFFFF; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/mips32/src/interrupt.c |
---|
38,12 → 38,12 |
#include <arch.h> |
#include <arch/cp0.h> |
#include <time/clock.h> |
#include <arch/drivers/arc.h> |
#include <ipc/sysipc.h> |
#include <ddi/device.h> |
#define IRQ_COUNT 8 |
#define TIMER_IRQ 7 |
#define DORDER_IRQ 5 |
#define IRQ_COUNT 8 |
#define TIMER_IRQ 7 |
function virtual_timer_fnc = NULL; |
static irq_t timer_irq; |
101,12 → 101,12 |
cp0_compare_write(nextcount); |
} |
static irq_ownership_t timer_claim(irq_t *irq) |
static irq_ownership_t timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void timer_irq_handler(irq_t *irq) |
static void timer_irq_handler(irq_t *irq, void *arg, ...) |
{ |
unsigned long drift; |
/branches/dd/kernel/arch/mips32/src/start.S |
---|
31,7 → 31,7 |
#include <arch/asm/boot.h> |
#include <arch/context_offset.h> |
#include <arch/stack.h> |
.text |
.set noat |
75,6 → 75,18 |
mfhi $at |
sw $at, EOFFSET_HI(\r) |
#ifdef CONFIG_DEBUG_ALLREGS |
sw $s0, EOFFSET_S0(\r) |
sw $s1, EOFFSET_S1(\r) |
sw $s2, EOFFSET_S2(\r) |
sw $s3, EOFFSET_S3(\r) |
sw $s4, EOFFSET_S4(\r) |
sw $s5, EOFFSET_S5(\r) |
sw $s6, EOFFSET_S6(\r) |
sw $s7, EOFFSET_S7(\r) |
sw $s8, EOFFSET_S8(\r) |
#endif |
sw $gp, EOFFSET_GP(\r) |
sw $ra, EOFFSET_RA(\r) |
sw $k1, EOFFSET_K1(\r) |
120,6 → 132,17 |
lw $t8, EOFFSET_T8(\r) |
lw $t9, EOFFSET_T9(\r) |
#ifdef CONFIG_DEBUG_ALLREGS |
lw $s0, EOFFSET_S0(\r) |
lw $s1, EOFFSET_S1(\r) |
lw $s2, EOFFSET_S2(\r) |
lw $s3, EOFFSET_S3(\r) |
lw $s4, EOFFSET_S4(\r) |
lw $s5, EOFFSET_S5(\r) |
lw $s6, EOFFSET_S6(\r) |
lw $s7, EOFFSET_S7(\r) |
lw $s8, EOFFSET_S8(\r) |
#endif |
lw $gp, EOFFSET_GP(\r) |
lw $ra, EOFFSET_RA(\r) |
lw $k1, EOFFSET_K1(\r) |
152,9 → 175,9 |
ori $k0, $k0, %lo(supervisor_sp) |
# Move $k0 (superveisor_sp) |
lw $k0, 0($k0) |
1: |
1: |
.endm |
.org 0x0 |
kernel_image_start: |
/* Load temporary stack */ |
161,12 → 184,31 |
lui $sp, %hi(end_stack) |
ori $sp, $sp, %lo(end_stack) |
/* Not sure about this, but might |
be needed for PIC code */ |
/* $a1 contains physical address of bootinfo_t */ |
/* $a2 contains size of bootinfo_t */ |
beq $a2, $0, bootinfo_end |
/* Not sure about this, but might be needed for PIC code???? */ |
lui $gp, 0x8000 |
/* $a1 contains physical address of bootinfo_t */ |
lui $a3, %hi(bootinfo) |
ori $a3, $a3, %lo(bootinfo) |
bootinfo_loop: |
lw $v0, 0($a1) |
sw $v0, 0($a3) |
addi $a1, $a1, 4 |
addi $a3, $a3, 4 |
addi $a2, $a2, -4 |
bgtz $a2, bootinfo_loop |
nop |
bootinfo_end: |
jal arch_pre_main |
nop |
186,8 → 228,8 |
exception_entry: |
j exception_handler |
nop |
nop |
exception_handler: |
KERNEL_STACK_TO_K0 |
sub $k0, REGISTER_SPACE |
196,17 → 238,17 |
mfc0 $k0, $cause |
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1 |
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2 |
sub $k0, 8 # 8 = SYSCALL |
sra $k0, $k0, 0x2 # cp0_exc_cause() part 1 |
andi $k0, $k0, 0x1f # cp0_exc_cause() part 2 |
sub $k0, 8 # 8 = SYSCALL |
beqz $k0, syscall_shortcut |
add $k0, 8 # Revert $k0 back to correct exc number |
add $k0, 8 # Revert $k0 back to correct exc number |
REGISTERS_STORE_AND_EXC_RESET $sp |
move $a1, $sp |
jal exc_dispatch # exc_dispatch(excno, register_space) |
jal exc_dispatch # exc_dispatch(excno, register_space) |
move $a0, $k0 |
REGISTERS_LOAD $sp |
307,7 → 349,5 |
userspace_asm: |
add $sp, $a0, 0 |
add $v0, $a1, 0 |
add $t9, $a2, 0 # Set up correct entry into PIC code |
xor $a0, $a0, $a0 # $a0 is defined to hold pcb_ptr |
# set it to 0 |
add $t9, $a2, 0 # Set up correct entry into PIC code |
eret |
/branches/dd/kernel/arch/mips32/src/exception.c |
---|
45,6 → 45,7 |
#include <print.h> |
#include <interrupt.h> |
#include <func.h> |
#include <console/kconsole.h> |
#include <ddi/irq.h> |
#include <arch/debugger.h> |
88,10 → 89,10 |
static void unhandled_exception(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unhandled exception %s.", exctable[n]); |
fault_if_from_uspace(istate, "unhandled exception %s", exctable[n]); |
print_regdump(istate); |
panic("Unhandled exception %s.", exctable[n]); |
panic("unhandled exception %s\n", exctable[n]); |
} |
static void reserved_instr_exception(int n, istate_t *istate) |
132,8 → 133,8 |
if (cp0_cause_coperr(cp0_cause_read()) == fpu_cop_id) |
scheduler_fpu_lazy_request(); |
else { |
fault_if_from_uspace(istate, "Unhandled Coprocessor Unusable Exception."); |
panic("Unhandled Coprocessor Unusable Exception."); |
fault_if_from_uspace(istate, "unhandled Coprocessor Unusable Exception"); |
panic("unhandled Coprocessor Unusable Exception\n"); |
} |
} |
#endif |
144,7 → 145,7 |
int i; |
/* decode interrupt number and process the interrupt */ |
cause = (cp0_cause_read() >> 8) & 0xff; |
cause = (cp0_cause_read() >> 8) &0xff; |
for (i = 0; i < 8; i++) { |
if (cause & (1 << i)) { |
153,7 → 154,7 |
/* |
* The IRQ handler was found. |
*/ |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
160,8 → 161,7 |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%u: spurious interrupt (inum=%d)\n", |
CPU->id, i); |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, i); |
#endif |
} |
} |
171,7 → 171,7 |
/** Handle syscall userspace call */ |
static void syscall_exception(int n, istate_t *istate) |
{ |
panic("Syscall is handled through shortcut."); |
panic("Syscall is handled through shortcut"); |
} |
void exception_init(void) |
/branches/dd/kernel/arch/mips32/src/cache.c |
---|
38,7 → 38,7 |
void cache_error(istate_t *istate) |
{ |
panic("cache_error exception (epc=%p).", istate->epc); |
panic("cache_error exception (epc=%p)\n", istate->epc); |
} |
/** @} |
/branches/dd/kernel/arch/mips32/src/fpu_context.c |
---|
40,7 → 40,7 |
void fpu_disable(void) |
{ |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
cp0_status_write(cp0_status_read() & ~cp0_status_fpu_bit); |
#endif |
} |
47,7 → 47,7 |
void fpu_enable(void) |
{ |
#ifdef CONFIG_FPU |
#ifdef ARCH_HAS_FPU |
cp0_status_write(cp0_status_read() | cp0_status_fpu_bit); |
#endif |
} |
/branches/dd/kernel/arch/mips32/src/asm.S |
---|
27,17 → 27,17 |
# |
#include <arch/asm/regname.h> |
.text |
.macro cp0_read reg |
mfc0 $2, \reg |
mfc0 $2,\reg |
j $31 |
nop |
.endm |
.macro cp0_write reg |
mtc0 $4, \reg |
mtc0 $4,\reg |
j $31 |
nop |
.endm |
46,11 → 46,6 |
.set noreorder |
.set nomacro |
.global asm_delay_loop |
asm_delay_loop: |
j $31 |
nop |
.global cpu_halt |
cpu_halt: |
j cpu_halt |
71,238 → 66,234 |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
move $t2, $a0 # save dst |
addiu $v0, $a1, 3 |
li $v1, -4 # 0xfffffffffffffffc |
and $v0, $v0, $v1 |
beq $a1, $v0, 3f |
move $t0, $a0 |
0: |
beq $a2, $zero, 2f |
move $a3, $zero |
1: |
addu $v0, $a1, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t0, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 1b |
sb $a0, 0($v1) |
2: |
jr $ra |
move $v0, $t2 |
3: |
addiu $v0, $a0, 3 |
and $v0, $v0, $v1 |
bne $a0, $v0, 0b |
srl $t1, $a2, 2 |
beq $t1, $zero, 5f |
move $a3, $zero |
move $a3, $zero |
move $a0, $zero |
4: |
addu $v0, $a1, $a0 |
lw $v1, 0($v0) |
addiu $a3, $a3, 1 |
addu $v0, $t0, $a0 |
sw $v1, 0($v0) |
bne $a3, $t1, 4b |
addiu $a0, $a0, 4 |
5: |
andi $a2, $a2, 0x3 |
beq $a2, $zero, 2b |
nop |
sll $v0, $a3, 2 |
addu $t1, $v0, $t0 |
move $a3, $zero |
addu $t0, $v0, $a1 |
6: |
addu $v0, $t0, $a3 |
lbu $a0, 0($v0) |
addu $v1, $t1, $a3 |
addiu $a3, $a3, 1 |
bne $a3, $a2, 6b |
sb $a0, 0($v1) |
jr $ra |
move $v0, $t2 |
addiu $v0,$a1,3 |
li $v1,-4 # 0xfffffffffffffffc |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
0: |
beq $a2,$zero,2f |
move $a3,$zero |
1: |
addu $v0,$a1,$a3 |
lbu $a0,0($v0) |
addu $v1,$t0,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,1b |
sb $a0,0($v1) |
2: |
jr $ra |
move $v0,$a1 |
3: |
addiu $v0,$a0,3 |
and $v0,$v0,$v1 |
bne $a0,$v0,0b |
srl $t1,$a2,2 |
beq $t1,$zero,5f |
move $a3,$zero |
move $a3,$zero |
move $a0,$zero |
4: |
addu $v0,$a1,$a0 |
lw $v1,0($v0) |
addiu $a3,$a3,1 |
addu $v0,$t0,$a0 |
sw $v1,0($v0) |
bne $a3,$t1,4b |
addiu $a0,$a0,4 |
5: |
andi $a2,$a2,0x3 |
beq $a2,$zero,2b |
nop |
sll $v0,$a3,2 |
addu $t1,$v0,$t0 |
move $a3,$zero |
addu $t0,$v0,$a1 |
6: |
addu $v0,$t0,$a3 |
lbu $a0,0($v0) |
addu $v1,$t1,$a3 |
addiu $a3,$a3,1 |
bne $a3,$a2,6b |
sb $a0,0($v1) |
jr $ra |
move $v0,$a1 |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
jr $ra |
move $v0, $zero |
jr $ra |
move $v0, $zero |
.macro fpu_gp_save reg ctx |
mfc1 $t0, $\reg |
sw $t0, \reg * 4(\ctx) |
mfc1 $t0,$\reg |
sw $t0, \reg*4(\ctx) |
.endm |
.macro fpu_gp_restore reg ctx |
lw $t0, \reg * 4(\ctx) |
mtc1 $t0, $\reg |
lw $t0, \reg*4(\ctx) |
mtc1 $t0,$\reg |
.endm |
.macro fpu_ct_save reg ctx |
cfc1 $t0, $1 |
sw $t0, (\reg + 32) * 4(\ctx) |
cfc1 $t0,$1 |
sw $t0, (\reg+32)*4(\ctx) |
.endm |
.macro fpu_ct_restore reg ctx |
lw $t0, (\reg + 32) * 4(\ctx) |
ctc1 $t0, $\reg |
lw $t0, (\reg+32)*4(\ctx) |
ctc1 $t0,$\reg |
.endm |
.global fpu_context_save |
fpu_context_save: |
#ifdef CONFIG_FPU |
fpu_gp_save 0, $a0 |
fpu_gp_save 1, $a0 |
fpu_gp_save 2, $a0 |
fpu_gp_save 3, $a0 |
fpu_gp_save 4, $a0 |
fpu_gp_save 5, $a0 |
fpu_gp_save 6, $a0 |
fpu_gp_save 7, $a0 |
fpu_gp_save 8, $a0 |
fpu_gp_save 9, $a0 |
fpu_gp_save 10, $a0 |
fpu_gp_save 11, $a0 |
fpu_gp_save 12, $a0 |
fpu_gp_save 13, $a0 |
fpu_gp_save 14, $a0 |
fpu_gp_save 15, $a0 |
fpu_gp_save 16, $a0 |
fpu_gp_save 17, $a0 |
fpu_gp_save 18, $a0 |
fpu_gp_save 19, $a0 |
fpu_gp_save 20, $a0 |
fpu_gp_save 21, $a0 |
fpu_gp_save 22, $a0 |
fpu_gp_save 23, $a0 |
fpu_gp_save 24, $a0 |
fpu_gp_save 25, $a0 |
fpu_gp_save 26, $a0 |
fpu_gp_save 27, $a0 |
fpu_gp_save 28, $a0 |
fpu_gp_save 29, $a0 |
fpu_gp_save 30, $a0 |
fpu_gp_save 31, $a0 |
fpu_ct_save 1, $a0 |
fpu_ct_save 2, $a0 |
fpu_ct_save 3, $a0 |
fpu_ct_save 4, $a0 |
fpu_ct_save 5, $a0 |
fpu_ct_save 6, $a0 |
fpu_ct_save 7, $a0 |
fpu_ct_save 8, $a0 |
fpu_ct_save 9, $a0 |
fpu_ct_save 10, $a0 |
fpu_ct_save 11, $a0 |
fpu_ct_save 12, $a0 |
fpu_ct_save 13, $a0 |
fpu_ct_save 14, $a0 |
fpu_ct_save 15, $a0 |
fpu_ct_save 16, $a0 |
fpu_ct_save 17, $a0 |
fpu_ct_save 18, $a0 |
fpu_ct_save 19, $a0 |
fpu_ct_save 20, $a0 |
fpu_ct_save 21, $a0 |
fpu_ct_save 22, $a0 |
fpu_ct_save 23, $a0 |
fpu_ct_save 24, $a0 |
fpu_ct_save 25, $a0 |
fpu_ct_save 26, $a0 |
fpu_ct_save 27, $a0 |
fpu_ct_save 28, $a0 |
fpu_ct_save 29, $a0 |
fpu_ct_save 30, $a0 |
fpu_ct_save 31, $a0 |
#endif |
#ifdef ARCH_HAS_FPU |
fpu_gp_save 0,$a0 |
fpu_gp_save 1,$a0 |
fpu_gp_save 2,$a0 |
fpu_gp_save 3,$a0 |
fpu_gp_save 4,$a0 |
fpu_gp_save 5,$a0 |
fpu_gp_save 6,$a0 |
fpu_gp_save 7,$a0 |
fpu_gp_save 8,$a0 |
fpu_gp_save 9,$a0 |
fpu_gp_save 10,$a0 |
fpu_gp_save 11,$a0 |
fpu_gp_save 12,$a0 |
fpu_gp_save 13,$a0 |
fpu_gp_save 14,$a0 |
fpu_gp_save 15,$a0 |
fpu_gp_save 16,$a0 |
fpu_gp_save 17,$a0 |
fpu_gp_save 18,$a0 |
fpu_gp_save 19,$a0 |
fpu_gp_save 20,$a0 |
fpu_gp_save 21,$a0 |
fpu_gp_save 22,$a0 |
fpu_gp_save 23,$a0 |
fpu_gp_save 24,$a0 |
fpu_gp_save 25,$a0 |
fpu_gp_save 26,$a0 |
fpu_gp_save 27,$a0 |
fpu_gp_save 28,$a0 |
fpu_gp_save 29,$a0 |
fpu_gp_save 30,$a0 |
fpu_gp_save 31,$a0 |
fpu_ct_save 1,$a0 |
fpu_ct_save 2,$a0 |
fpu_ct_save 3,$a0 |
fpu_ct_save 4,$a0 |
fpu_ct_save 5,$a0 |
fpu_ct_save 6,$a0 |
fpu_ct_save 7,$a0 |
fpu_ct_save 8,$a0 |
fpu_ct_save 9,$a0 |
fpu_ct_save 10,$a0 |
fpu_ct_save 11,$a0 |
fpu_ct_save 12,$a0 |
fpu_ct_save 13,$a0 |
fpu_ct_save 14,$a0 |
fpu_ct_save 15,$a0 |
fpu_ct_save 16,$a0 |
fpu_ct_save 17,$a0 |
fpu_ct_save 18,$a0 |
fpu_ct_save 19,$a0 |
fpu_ct_save 20,$a0 |
fpu_ct_save 21,$a0 |
fpu_ct_save 22,$a0 |
fpu_ct_save 23,$a0 |
fpu_ct_save 24,$a0 |
fpu_ct_save 25,$a0 |
fpu_ct_save 26,$a0 |
fpu_ct_save 27,$a0 |
fpu_ct_save 28,$a0 |
fpu_ct_save 29,$a0 |
fpu_ct_save 30,$a0 |
fpu_ct_save 31,$a0 |
#endif |
j $ra |
nop |
.global fpu_context_restore |
fpu_context_restore: |
#ifdef CONFIG_FPU |
fpu_gp_restore 0, $a0 |
fpu_gp_restore 1, $a0 |
fpu_gp_restore 2, $a0 |
fpu_gp_restore 3, $a0 |
fpu_gp_restore 4, $a0 |
fpu_gp_restore 5, $a0 |
fpu_gp_restore 6, $a0 |
fpu_gp_restore 7, $a0 |
fpu_gp_restore 8, $a0 |
fpu_gp_restore 9, $a0 |
fpu_gp_restore 10, $a0 |
fpu_gp_restore 11, $a0 |
fpu_gp_restore 12, $a0 |
fpu_gp_restore 13, $a0 |
fpu_gp_restore 14, $a0 |
fpu_gp_restore 15, $a0 |
fpu_gp_restore 16, $a0 |
fpu_gp_restore 17, $a0 |
fpu_gp_restore 18, $a0 |
fpu_gp_restore 19, $a0 |
fpu_gp_restore 20, $a0 |
fpu_gp_restore 21, $a0 |
fpu_gp_restore 22, $a0 |
fpu_gp_restore 23, $a0 |
fpu_gp_restore 24, $a0 |
fpu_gp_restore 25, $a0 |
fpu_gp_restore 26, $a0 |
fpu_gp_restore 27, $a0 |
fpu_gp_restore 28, $a0 |
fpu_gp_restore 29, $a0 |
fpu_gp_restore 30, $a0 |
fpu_gp_restore 31, $a0 |
fpu_ct_restore 1, $a0 |
fpu_ct_restore 2, $a0 |
fpu_ct_restore 3, $a0 |
fpu_ct_restore 4, $a0 |
fpu_ct_restore 5, $a0 |
fpu_ct_restore 6, $a0 |
fpu_ct_restore 7, $a0 |
fpu_ct_restore 8, $a0 |
fpu_ct_restore 9, $a0 |
fpu_ct_restore 10, $a0 |
fpu_ct_restore 11, $a0 |
fpu_ct_restore 12, $a0 |
fpu_ct_restore 13, $a0 |
fpu_ct_restore 14, $a0 |
fpu_ct_restore 15, $a0 |
fpu_ct_restore 16, $a0 |
fpu_ct_restore 17, $a0 |
fpu_ct_restore 18, $a0 |
fpu_ct_restore 19, $a0 |
fpu_ct_restore 20, $a0 |
fpu_ct_restore 21, $a0 |
fpu_ct_restore 22, $a0 |
fpu_ct_restore 23, $a0 |
fpu_ct_restore 24, $a0 |
fpu_ct_restore 25, $a0 |
fpu_ct_restore 26, $a0 |
fpu_ct_restore 27, $a0 |
fpu_ct_restore 28, $a0 |
fpu_ct_restore 29, $a0 |
fpu_ct_restore 30, $a0 |
fpu_ct_restore 31, $a0 |
#endif |
#ifdef ARCH_HAS_FPU |
fpu_gp_restore 0,$a0 |
fpu_gp_restore 1,$a0 |
fpu_gp_restore 2,$a0 |
fpu_gp_restore 3,$a0 |
fpu_gp_restore 4,$a0 |
fpu_gp_restore 5,$a0 |
fpu_gp_restore 6,$a0 |
fpu_gp_restore 7,$a0 |
fpu_gp_restore 8,$a0 |
fpu_gp_restore 9,$a0 |
fpu_gp_restore 10,$a0 |
fpu_gp_restore 11,$a0 |
fpu_gp_restore 12,$a0 |
fpu_gp_restore 13,$a0 |
fpu_gp_restore 14,$a0 |
fpu_gp_restore 15,$a0 |
fpu_gp_restore 16,$a0 |
fpu_gp_restore 17,$a0 |
fpu_gp_restore 18,$a0 |
fpu_gp_restore 19,$a0 |
fpu_gp_restore 20,$a0 |
fpu_gp_restore 21,$a0 |
fpu_gp_restore 22,$a0 |
fpu_gp_restore 23,$a0 |
fpu_gp_restore 24,$a0 |
fpu_gp_restore 25,$a0 |
fpu_gp_restore 26,$a0 |
fpu_gp_restore 27,$a0 |
fpu_gp_restore 28,$a0 |
fpu_gp_restore 29,$a0 |
fpu_gp_restore 30,$a0 |
fpu_gp_restore 31,$a0 |
fpu_ct_restore 1,$a0 |
fpu_ct_restore 2,$a0 |
fpu_ct_restore 3,$a0 |
fpu_ct_restore 4,$a0 |
fpu_ct_restore 5,$a0 |
fpu_ct_restore 6,$a0 |
fpu_ct_restore 7,$a0 |
fpu_ct_restore 8,$a0 |
fpu_ct_restore 9,$a0 |
fpu_ct_restore 10,$a0 |
fpu_ct_restore 11,$a0 |
fpu_ct_restore 12,$a0 |
fpu_ct_restore 13,$a0 |
fpu_ct_restore 14,$a0 |
fpu_ct_restore 15,$a0 |
fpu_ct_restore 16,$a0 |
fpu_ct_restore 17,$a0 |
fpu_ct_restore 18,$a0 |
fpu_ct_restore 19,$a0 |
fpu_ct_restore 20,$a0 |
fpu_ct_restore 21,$a0 |
fpu_ct_restore 22,$a0 |
fpu_ct_restore 23,$a0 |
fpu_ct_restore 24,$a0 |
fpu_ct_restore 25,$a0 |
fpu_ct_restore 26,$a0 |
fpu_ct_restore 27,$a0 |
fpu_ct_restore 28,$a0 |
fpu_ct_restore 29,$a0 |
fpu_ct_restore 30,$a0 |
fpu_ct_restore 31,$a0 |
#endif |
j $ra |
nop |
/branches/dd/kernel/arch/mips32/src/dummy.S |
---|
0,0 → 1,41 |
# |
# Copyright (c) 2003-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.set noat |
.global calibrate_delay_loop |
.global asm_delay_loop |
.global dummy |
calibrate_delay_loop: |
asm_delay_loop: |
dummy: |
j $31 |
nop |
/branches/dd/kernel/arch/mips32/Makefile.inc |
---|
31,26 → 31,57 |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel |
TOOLCHAIN_DIR = /usr/local/mipsel |
KERNEL_LOAD_ADDRESS = 0x80100000 |
INIT_ADDRESS = 0x81000000 |
INIT_SIZE = 262144 |
GCC_CFLAGS += -mno-abicalls -G 0 -fno-zero-initialized-in-bss |
DEFS += -D__32_BITS__ |
DEFS += -D__32_BITS__ -DMACHINE=$(MACHINE) -DKERNEL_LOAD_ADDRESS=${KERNEL_LOAD_ADDRESS} -DINIT_ADDRESS=${INIT_ADDRESS} -DINIT_SIZE=${INIT_SIZE} |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with support for address space identifiers. |
# |
CONFIG_ASID = y |
CONFIG_ASID_FIFO = y |
## Accepted MACHINEs |
# |
ifeq ($(MACHINE),indy) |
# GCC 4.0.1 compiled for mipsEL has problems compiling in |
# BigEndian mode with the swl/swr/lwl/lwr instructions. |
# We have to compile it with mips-sgi-irix5 to get it right. |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips --impure |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
KERNEL_LOAD_ADDRESS = 0x88002000 |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -march=r4600 |
INIT_ADDRESS = 0 |
INIT_SIZE = 0 |
endif |
ifeq ($(MACHINE),lgxemul) |
BFD_NAME = elf32-tradlittlemips |
BFD = binary |
GCC_CFLAGS += -mips3 |
GCC_CFLAGS += -DFB_INVERT_ENDIAN -DARCH_HAS_FPU -mips3 |
endif |
ifeq ($(MACHINE),bgxemul) |
BFD_NAME = elf32-bigmips |
BFD = ecoff-bigmips |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips |
TARGET = mips-sgi-irix5 |
GCC_CFLAGS += -EB -DBIG_ENDIAN -mips3 |
TOOLCHAIN_DIR = /usr/local/mips/bin |
GCC_CFLAGS += -EB -DBIG_ENDIAN -DARCH_HAS_FPU -mips3 |
INIT_ADDRESS = 0x81800000 |
endif |
ifeq ($(MACHINE),simics) |
# SIMICS 4kc emulation is broken, although for instructions |
67,24 → 98,32 |
GCC_CFLAGS += -mhard-float -mips3 |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/start.S \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/panic.S \ |
arch/$(KARCH)/src/mips32.c \ |
arch/$(KARCH)/src/console.c \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/exception.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/cache.c \ |
arch/$(KARCH)/src/debugger.c \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/msim.c \ |
arch/$(KARCH)/src/smp/dorder.c \ |
arch/$(KARCH)/src/smp/smp.c |
arch/$(ARCH)/src/start.S \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/panic.S \ |
arch/$(ARCH)/src/mips32.c \ |
arch/$(ARCH)/src/dummy.S \ |
arch/$(ARCH)/src/console.c \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/exception.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/cache.c \ |
arch/$(ARCH)/src/debugger.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/arc.c \ |
arch/$(ARCH)/src/drivers/msim.c \ |
arch/$(ARCH)/src/drivers/serial.c \ |
arch/$(ARCH)/src/smp/order.c |
/branches/dd/kernel/arch/mips32/_link.ld.in |
---|
1,17 → 1,15 |
/* |
* MIPS32 linker script |
* |
* MIPS32 linker script |
* |
* kernel text |
* kernel data |
* |
* |
*/ |
#undef mips |
#define mips mips |
#define KERNEL_LOAD_ADDRESS 0x80100000 |
OUTPUT_ARCH(mips) |
OUTPUT_ARCH(mips) |
ENTRY(kernel_image_start) |
SECTIONS { |
23,9 → 21,9 |
} |
.data : { |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.data); /* initialized data */ |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
hardcoded_load_address = .; |
35,21 → 33,21 |
*(.reginfo); |
*(.sbss); |
*(.scommon); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
symbol_table = .; |
*(symtab.*); |
*(symtab.*); |
} |
_gp = . + 0x8000; |
.lit8 : { *(.lit8) } |
.lit4 : { *(.lit4) } |
kdata_end = .; |
/DISCARD/ : { |
*(.mdebug*); |
*(.pdr); |
*(.comment); |
*(.note); |
*(.mdebug*); |
*(.pdr); |
*(.comment); |
*(.note); |
} |
} |
/branches/dd/kernel/arch/ia32/include/syscall.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32/include/boot/memmap.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,29 → 35,24 |
#ifndef KERN_ia32_MEMMAP_H_ |
#define KERN_ia32_MEMMAP_H_ |
/* E820h memory range types */ |
/* E820h memory range types - other values*/ |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* Free memory */ |
#define MEMMAP_MEMORY_AVAILABLE 1 |
/* size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
/* Not available for OS */ |
#define MEMMAP_MEMORY_RESERVED 2 |
/* OS may use it after reading ACPI table */ |
#define MEMMAP_MEMORY_ACPI 3 |
/* Unusable, required to be saved and restored across an NVS sleep */ |
#define MEMMAP_MEMORY_NVS 4 |
/* Corrupted memory */ |
#define MEMMAP_MEMORY_UNUSABLE 5 |
/* Size of one entry */ |
#define MEMMAP_E820_RECORD_SIZE 20 |
/* Maximum entries */ |
#define MEMMAP_E820_MAX_RECORDS 32 |
#ifndef __ASM__ |
#include <arch/types.h> |
/branches/dd/kernel/arch/ia32/include/boot/boot.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,24 → 35,15 |
#ifndef KERN_ia32_BOOT_H_ |
#define KERN_ia32_BOOT_H_ |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define BOOT_OFFSET 0x108000 |
#define AP_BOOT_OFFSET 0x8000 |
#define BOOT_STACK_SIZE 0x400 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#define MULTIBOOT_HEADER_MAGIC 0x1BADB002 |
#define MULTIBOOT_HEADER_FLAGS 0x00010003 |
#ifndef __ASM__ |
#define MULTIBOOT_LOADER_MAGIC 0x2BADB002 |
#ifdef CONFIG_SMP |
/* This is only a symbol so the type is dummy. Obtain the value using &. */ |
extern int _hardcoded_unmapped_size; |
#endif /* CONFIG_SMP */ |
#endif /* __ASM__ */ |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/mm/frame.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32mm |
/** @addtogroup ia32mm |
* @{ |
*/ |
/** @file |
35,8 → 35,8 |
#ifndef KERN_ia32_FRAME_H_ |
#define KERN_ia32_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
/branches/dd/kernel/arch/ia32/include/mm/page.h |
---|
40,6 → 40,8 |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
126,8 → 128,6 |
#include <mm/mm.h> |
#include <arch/interrupt.h> |
#include <arch/types.h> |
#include <typedefs.h> |
/* Page fault error codes. */ |
/branches/dd/kernel/arch/ia32/include/mm/as.h |
---|
42,7 → 42,7 |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH - (PAGE_SIZE - 1)) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) |
typedef struct { |
} as_arch_t; |
/branches/dd/kernel/arch/ia32/include/mm/tlb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32mm |
/** @addtogroup ia32mm |
* @{ |
*/ |
/** @file |
35,6 → 35,9 |
#ifndef KERN_ia32_TLB_H_ |
#define KERN_ia32_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/interrupt.h |
---|
72,6 → 72,10 |
uint32_t eax; |
uint32_t ecx; |
uint32_t edx; |
uint32_t esi; |
uint32_t edi; |
uint32_t ebp; |
uint32_t ebx; |
uint32_t gs; |
uint32_t fs; |
/branches/dd/kernel/arch/ia32/include/asm.h |
---|
27,7 → 27,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
38,7 → 38,6 |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <typedefs.h> |
#include <config.h> |
extern uint32_t interrupt_handler_size; |
57,7 → 56,6 |
/** Halt CPU |
* |
* Halt the current CPU until interrupt event. |
* |
*/ |
static inline void cpu_halt(void) |
{ |
70,22 → 68,16 |
} |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ( \ |
"movl %%" #reg ", %[res]" \ |
: [res] "=r" (res) \ |
); \ |
return res; \ |
} |
{ \ |
unative_t res; \ |
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ( \ |
"movl %[regn], %%" #reg \ |
:: [regn] "r" (regn) \ |
); \ |
} |
{ \ |
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0) |
GEN_READ_REG(cr2) |
112,14 → 104,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline void outb(uint16_t port, uint8_t val) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Word to port |
128,14 → 116,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
static inline void outw(uint16_t port, uint16_t val) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Double word to port |
144,14 → 128,10 |
* |
* @param port Port to write to |
* @param val Value to write |
* |
*/ |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
static inline void outl(uint16_t port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); |
} |
/** Byte from port |
160,18 → 140,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline uint8_t inb(uint16_t port) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
181,18 → 155,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint16_t pio_read_16(ioport16_t *port) |
static inline uint16_t inw(uint16_t port) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
202,18 → 170,12 |
* |
* @param port Port to read from |
* @return Value read |
* |
*/ |
static inline uint32_t pio_read_32(ioport32_t *port) |
static inline uint32_t inl(uint16_t port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); |
return val; |
} |
223,19 → 185,16 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
"pushf\n\t" |
"popl %0\n\t" |
"sti\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
245,19 → 204,16 |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
* |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
"pushf\n\t" |
"popl %0\n\t" |
"cli\n" |
: [v] "=r" (v) |
: "=r" (v) |
); |
return v; |
} |
266,14 → 222,13 |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
* |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
asm volatile ( |
"pushl %[ipl]\n" |
"pushl %0\n\t" |
"popf\n" |
:: [ipl] "r" (ipl) |
: : "r" (ipl) |
); |
} |
280,51 → 235,23 |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
* |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
ipl_t v; |
asm volatile ( |
"pushf\n" |
"popl %[v]\n" |
: [v] "=r" (v) |
"pushf\n\t" |
"popl %0\n" |
: "=r" (v) |
); |
return v; |
} |
/** Write to MSR */ |
static inline void write_msr(uint32_t msr, uint64_t value) |
{ |
asm volatile ( |
"wrmsr" |
:: "c" (msr), "a" ((uint32_t) (value)), |
"d" ((uint32_t) (value >> 32)) |
); |
} |
static inline uint64_t read_msr(uint32_t msr) |
{ |
uint32_t ax, dx; |
asm volatile ( |
"rdmsr" |
: "=a" (ax), "=d" (dx) |
: "c" (msr) |
); |
return ((uint64_t) dx << 32) | ax; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
* |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
331,8 → 258,8 |
uintptr_t v; |
asm volatile ( |
"andl %%esp, %[v]\n" |
: [v] "=r" (v) |
"andl %%esp, %0\n" |
: "=r" (v) |
: "0" (~(STACK_SIZE - 1)) |
); |
343,12 → 270,11 |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%eip, %[ip]" |
: [ip] "=r" (ip) |
); |
"mov %%eip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
355,66 → 281,46 |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
* |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ( |
"invlpg %[addr]\n" |
:: [addr] "m" (*(unative_t *) addr) |
); |
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
* |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ( |
"lgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
* |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ( |
"sgdtl %[gdtr_reg]\n" |
:: [gdtr_reg] "m" (*gdtr_reg) |
); |
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load IDTR register from memory. |
* |
* @param idtr_reg Address of memory from where to load IDTR. |
* |
*/ |
static inline void idtr_load(ptr_16_32_t *idtr_reg) |
{ |
asm volatile ( |
"lidtl %[idtr_reg]\n" |
:: [idtr_reg] "m" (*idtr_reg) |
); |
asm volatile ("lidtl %0\n" : : "m" (*idtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
* |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ( |
"ltr %[sel]" |
:: [sel] "r" (sel) |
); |
asm volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/branches/dd/kernel/arch/ia32/include/smp/apic.h |
---|
105,8 → 105,8 |
#define MODEL_CLUSTER 0x0 |
/** Interrupt Command Register. */ |
#define ICRlo (0x300 / sizeof(uint32_t)) |
#define ICRhi (0x310 / sizeof(uint32_t)) |
#define ICRlo (0x300/sizeof(uint32_t)) |
#define ICRhi (0x310/sizeof(uint32_t)) |
typedef struct { |
union { |
uint32_t lo; |
133,10 → 133,10 |
} __attribute__ ((packed)) icr_t; |
/* End Of Interrupt. */ |
#define EOI (0x0b0 / sizeof(uint32_t)) |
#define EOI (0x0b0/sizeof(uint32_t)) |
/** Error Status Register. */ |
#define ESR (0x280 / sizeof(uint32_t)) |
#define ESR (0x280/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
uint8_t err_bitmap; |
154,7 → 154,7 |
} esr_t; |
/* Task Priority Register */ |
#define TPR (0x080 / sizeof(uint32_t)) |
#define TPR (0x080/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
164,7 → 164,7 |
} tpr_t; |
/** Spurious-Interrupt Vector Register. */ |
#define SVR (0x0f0 / sizeof(uint32_t)) |
#define SVR (0x0f0/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
176,7 → 176,7 |
} svr_t; |
/** Time Divide Configuration Register. */ |
#define TDCR (0x3e0 / sizeof(uint32_t)) |
#define TDCR (0x3e0/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
186,13 → 186,13 |
} tdcr_t; |
/* Initial Count Register for Timer */ |
#define ICRT (0x380 / sizeof(uint32_t)) |
#define ICRT (0x380/sizeof(uint32_t)) |
/* Current Count Register for Timer */ |
#define CCRT (0x390 / sizeof(uint32_t)) |
#define CCRT (0x390/sizeof(uint32_t)) |
/** LVT Timer register. */ |
#define LVT_Tm (0x320 / sizeof(uint32_t)) |
#define LVT_Tm (0x320/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
207,8 → 207,8 |
} lvt_tm_t; |
/** LVT LINT registers. */ |
#define LVT_LINT0 (0x350 / sizeof(uint32_t)) |
#define LVT_LINT1 (0x360 / sizeof(uint32_t)) |
#define LVT_LINT0 (0x350/sizeof(uint32_t)) |
#define LVT_LINT1 (0x360/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
225,7 → 225,7 |
} lvt_lint_t; |
/** LVT Error register. */ |
#define LVT_Err (0x370 / sizeof(uint32_t)) |
#define LVT_Err (0x370/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
239,7 → 239,7 |
} lvt_error_t; |
/** Local APIC ID Register. */ |
#define L_APIC_ID (0x020 / sizeof(uint32_t)) |
#define L_APIC_ID (0x020/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
249,14 → 249,14 |
} l_apic_id_t; |
/** Local APIC Version Register */ |
#define LAVR (0x030 / sizeof(uint32_t)) |
#define LAVR (0x030/sizeof(uint32_t)) |
#define LAVR_Mask 0xff |
#define is_local_apic(x) (((x) & LAVR_Mask & 0xf0) == 0x1) |
#define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0) == 0x0)) |
#define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14) |
#define is_local_apic(x) (((x)&LAVR_Mask&0xf0)==0x1) |
#define is_82489DX_apic(x) ((((x)&LAVR_Mask&0xf0)==0x0)) |
#define is_local_xapic(x) (((x)&LAVR_Mask)==0x14) |
/** Logical Destination Register. */ |
#define LDR (0x0d0 / sizeof(uint32_t)) |
#define LDR (0x0d0/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
266,7 → 266,7 |
} ldr_t; |
/** Destination Format Register. */ |
#define DFR (0x0e0 / sizeof(uint32_t)) |
#define DFR (0x0e0/sizeof(uint32_t)) |
typedef union { |
uint32_t value; |
struct { |
276,8 → 276,8 |
} dfr_t; |
/* IO APIC */ |
#define IOREGSEL (0x00 / sizeof(uint32_t)) |
#define IOWIN (0x10 / sizeof(uint32_t)) |
#define IOREGSEL (0x00/sizeof(uint32_t)) |
#define IOWIN (0x10/sizeof(uint32_t)) |
#define IOAPICID 0x00 |
#define IOAPICVER 0x01 |
/branches/dd/kernel/arch/ia32/include/cpuid.h |
---|
74,21 → 74,21 |
uint32_t val, ret; |
asm volatile ( |
"pushf\n" /* read flags */ |
"popl %[ret]\n" |
"movl %[ret], %[val]\n" |
"pushf\n" /* read flags */ |
"popl %0\n" |
"movl %0, %1\n" |
"btcl $21, %[val]\n" /* swap the ID bit */ |
"btcl $21, %1\n" /* swap the ID bit */ |
"pushl %[val]\n" /* propagate the change into flags */ |
"pushl %1\n" /* propagate the change into flags */ |
"popf\n" |
"pushf\n" |
"popl %[val]\n" |
"popl %1\n" |
"andl $(1 << 21), %[ret]\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %[val]\n" |
"xorl %[val], %[ret]\n" |
: [ret] "=r" (ret), [val] "=r" (val) |
"andl $(1 << 21), %0\n" /* interrested only in ID bit */ |
"andl $(1 << 21), %1\n" |
"xorl %1, %0\n" |
: "=r" (ret), "=r" (val) |
); |
return ret; |
98,8 → 98,7 |
{ |
asm volatile ( |
"cpuid\n" |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), |
"=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "=a" (info->cpuid_eax), "=b" (info->cpuid_ebx), "=c" (info->cpuid_ecx), "=d" (info->cpuid_edx) |
: "a" (cmd) |
); |
} |
/branches/dd/kernel/arch/ia32/include/types.h |
---|
35,6 → 35,10 |
#ifndef KERN_ia32_TYPES_H_ |
#define KERN_ia32_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
57,32 → 61,14 |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef struct { |
} fncptr_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
#define PRIp "x" /**< Format for uintptr_t. */ |
#define PRIs "u" /**< Format for size_t. */ |
#define PRIc "u" /**< Format for count_t. */ |
#define PRIi "u" /**< Format for index_t. */ |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
#define PRId8 "d" /**< Format for int8_t. */ |
#define PRId16 "d" /**< Format for int16_t. */ |
#define PRId32 "d" /**< Format for int32_t. */ |
#define PRId64 "lld" /**< Format for int64_t. */ |
#define PRIdn "d" /**< Format for native_t. */ |
#define PRIu8 "u" /**< Format for uint8_t. */ |
#define PRIu16 "u" /**< Format for uint16_t. */ |
#define PRIu32 "u" /**< Format for uint32_t. */ |
#define PRIu64 "llu" /**< Format for uint64_t. */ |
#define PRIun "u" /**< Format for unative_t. */ |
#define PRIx8 "x" /**< Format for hexadecimal (u)int8_t. */ |
#define PRIx16 "x" /**< Format for hexadecimal (u)int16_t. */ |
#define PRIx32 "x" /**< Format for hexadecimal (u)uint32_t. */ |
#define PRIx64 "llx" /**< Format for hexadecimal (u)int64_t. */ |
#define PRIxn "x" /**< Format for hexadecimal (u)native_t. */ |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; |
/branches/dd/kernel/arch/ia32/include/atomic.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
41,29 → 41,17 |
static inline void atomic_inc(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock incl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock incl %0\n" : "=m" (val->count)); |
#else |
asm volatile ( |
"incl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("incl %0\n" : "=m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
static inline void atomic_dec(atomic_t *val) { |
#ifdef CONFIG_SMP |
asm volatile ( |
"lock decl %[count]\n" |
: [count] "+m" (val->count) |
); |
asm volatile ("lock decl %0\n" : "=m" (val->count)); |
#else |
asm volatile ( |
"decl %[count]\n" |
: "+m" (val->count) |
); |
asm volatile ("decl %0\n" : "=m" (val->count)); |
#endif /* CONFIG_SMP */ |
} |
70,12 → 58,12 |
static inline long atomic_postinc(atomic_t *val) |
{ |
long r = 1; |
asm volatile ( |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r" (r) |
"lock xaddl %1, %0\n" |
: "=m" (val->count), "+r" (r) |
); |
return r; |
} |
84,23 → 72,23 |
long r = -1; |
asm volatile ( |
"lock xaddl %[r], %[count]\n" |
: [count] "+m" (val->count), [r] "+r"(r) |
"lock xaddl %1, %0\n" |
: "=m" (val->count), "+r"(r) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
static inline uint32_t test_and_set(atomic_t *val) { |
uint32_t v; |
asm volatile ( |
"movl $1, %[v]\n" |
"xchgl %[v], %[count]\n" |
: [v] "=r" (v), [count] "+m" (val->count) |
"movl $1, %0\n" |
"xchgl %0, %1\n" |
: "=r" (v),"=m" (val->count) |
); |
return v; |
110,23 → 98,23 |
static inline void atomic_lock_arch(atomic_t *val) |
{ |
uint32_t tmp; |
preemption_disable(); |
asm volatile ( |
"0:\n" |
"0:;" |
#ifdef CONFIG_HT |
"pause\n" /* Pentium 4's HT love this instruction */ |
"pause;" /* Pentium 4's HT love this instruction */ |
#endif |
"mov %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
"jnz 0b\n" /* lightweight looping on locked spinlock */ |
"mov %0, %1;" |
"testl %1, %1;" |
"jnz 0b;" /* Lightweight looping on locked spinlock */ |
"incl %[tmp]\n" /* now use the atomic operation */ |
"xchgl %[count], %[tmp]\n" |
"testl %[tmp], %[tmp]\n" |
"jnz 0b\n" |
: [count] "+m" (val->count), [tmp] "=&r" (tmp) |
); |
"incl %1;" /* now use the atomic operation */ |
"xchgl %0, %1;" |
"testl %1, %1;" |
"jnz 0b;" |
: "=m"(val->count),"=r"(tmp) |
); |
/* |
* Prevent critical section code from bleeding out this way up. |
*/ |
/branches/dd/kernel/arch/ia32/include/cpu.h |
---|
35,33 → 35,25 |
#ifndef KERN_ia32_CPU_H_ |
#define KERN_ia32_CPU_H_ |
#include <arch/pm.h> |
#include <arch/asm.h> |
#define EFLAGS_IF (1 << 9) |
#define EFLAGS_RF (1 << 16) |
#define CR4_OSFXSR_MASK (1<<9) |
/* Support for SYSENTER and SYSEXIT */ |
#define IA32_MSR_SYSENTER_CS 0x174 |
#define IA32_MSR_SYSENTER_ESP 0x175 |
#define IA32_MSR_SYSENTER_EIP 0x176 |
#ifndef __ASM__ |
#include <arch/pm.h> |
#include <arch/asm.h> |
typedef struct { |
unsigned int vendor; |
unsigned int family; |
unsigned int model; |
unsigned int stepping; |
int vendor; |
int family; |
int model; |
int stepping; |
struct tss *tss; |
count_t iomapver_copy; /** Copy of TASK's I/O Permission bitmap generation count. */ |
} cpu_arch_t; |
#endif |
#define CR4_OSFXSR_MASK (1<<9) |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/fpu_context.h |
---|
37,6 → 37,7 |
#include <arch/types.h> |
#define ARCH_HAS_FPU |
#define FPU_CONTEXT_ALIGN 16 |
void fpu_fxsr(void); |
/branches/dd/kernel/arch/ia32/include/memstr.h |
---|
35,13 → 35,116 |
#ifndef KERN_ia32_MEMSTR_H_ |
#define KERN_ia32_MEMSTR_H_ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
/** Copy memory |
* |
* Copy a given number of bytes (3rd argument) |
* from the memory location defined by 2nd argument |
* to the memory location defined by 1st argument. |
* The memory areas cannot overlap. |
* |
* @param dst Destination |
* @param src Source |
* @param cnt Number of bytes |
* @return Destination |
*/ |
static inline void * memcpy(void * dst, const void * src, size_t cnt) |
{ |
unative_t d0, d1, d2; |
extern void memsetw(void *dst, size_t cnt, uint16_t x); |
extern void memsetb(void *dst, size_t cnt, uint8_t x); |
asm volatile( |
/* copy all full dwords */ |
"rep movsl\n\t" |
/* load count again */ |
"movl %4, %%ecx\n\t" |
/* ecx = ecx mod 4 */ |
"andl $3, %%ecx\n\t" |
/* are there last <=3 bytes? */ |
"jz 1f\n\t" |
/* copy last <=3 bytes */ |
"rep movsb\n\t" |
/* exit from asm block */ |
"1:\n" |
: "=&c" (d0), "=&D" (d1), "=&S" (d2) |
: "0" ((unative_t) (cnt / 4)), "g" ((unative_t) cnt), "1" ((unative_t) dst), "2" ((unative_t) src) |
: "memory"); |
extern int memcmp(const void *a, const void *b, size_t cnt); |
return dst; |
} |
/** Compare memory regions for equality |
* |
* Compare a given number of bytes (3rd argument) |
* at memory locations defined by 1st and 2nd argument |
* for equality. If bytes are equal function returns 0. |
* |
* @param src Region 1 |
* @param dst Region 2 |
* @param cnt Number of bytes |
* @return Zero if bytes are equal, non-zero otherwise |
*/ |
static inline int memcmp(const void * src, const void * dst, size_t cnt) |
{ |
uint32_t d0, d1, d2; |
int ret; |
asm ( |
"repe cmpsb\n\t" |
"je 1f\n\t" |
"movl %3, %0\n\t" |
"addl $1, %0\n\t" |
"1:\n" |
: "=a" (ret), "=%S" (d0), "=&D" (d1), "=&c" (d2) |
: "0" (0), "1" ((unative_t) src), "2" ((unative_t) dst), "3" ((unative_t) cnt) |
); |
return ret; |
} |
/** Fill memory with words |
* Fill a given number of words (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of words |
* @param x Value to fill |
*/ |
static inline void memsetw(uintptr_t dst, size_t cnt, uint16_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosw\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
/** Fill memory with bytes |
* Fill a given number of bytes (2nd argument) |
* at memory defined by 1st argument with the |
* word value defined by 3rd argument. |
* |
* @param dst Destination |
* @param cnt Number of bytes |
* @param x Value to fill |
*/ |
static inline void memsetb(uintptr_t dst, size_t cnt, uint8_t x) |
{ |
uint32_t d0, d1; |
asm volatile ( |
"rep stosb\n\t" |
: "=&D" (d0), "=&c" (d1), "=a" (x) |
: "0" (dst), "1" (cnt), "2" (x) |
: "memory" |
); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/barrier.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
46,8 → 46,8 |
* Provisions are made to prevent compiler from reordering instructions itself. |
*/ |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
#define CS_ENTER_BARRIER() asm volatile ("" ::: "memory") |
#define CS_LEAVE_BARRIER() asm volatile ("" ::: "memory") |
static inline void cpuid_serialization(void) |
{ |
58,41 → 58,32 |
); |
} |
#if defined(CONFIG_FENCES_P4) |
#define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
#define read_barrier() asm volatile ("lfence\n" ::: "memory") |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#elif defined(CONFIG_FENCES_P3) |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() asm volatile ("sfence\n" ::: "memory") |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
#ifdef CONFIG_FENCES_P4 |
# define memory_barrier() asm volatile ("mfence\n" ::: "memory") |
# define read_barrier() asm volatile ("lfence\n" ::: "memory") |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#elif CONFIG_FENCES_P3 |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() asm volatile ("sfence\n" ::: "memory") |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#else |
#define memory_barrier() cpuid_serialization() |
#define read_barrier() cpuid_serialization() |
#ifdef CONFIG_WEAK_MEMORY |
#define write_barrier() cpuid_serialization() |
#else |
#define write_barrier() asm volatile ("" ::: "memory"); |
#endif |
# define memory_barrier() cpuid_serialization() |
# define read_barrier() cpuid_serialization() |
# ifdef CONFIG_WEAK_MEMORY |
# define write_barrier() cpuid_serialization() |
# else |
# define write_barrier() asm volatile( "" ::: "memory"); |
# endif |
#endif |
/* |
* On ia32, the hardware takes care about instruction and data cache coherence, |
* even on SMP systems. We issue a write barrier to be sure that writes |
* queueing in the store buffer drain to the memory (even though it would be |
* sufficient for them to drain to the D-cache). |
*/ |
#define smc_coherence(a) write_barrier() |
#define smc_coherence_block(a, l) write_barrier() |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/arch.h |
---|
1,5 → 1,5 |
/* |
* Copyright (c) 2009 Martin Decky |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
35,10 → 35,6 |
#ifndef KERN_ia32_ARCH_H_ |
#define KERN_ia32_ARCH_H_ |
#include <genarch/multiboot/multiboot.h> |
extern void arch_pre_main(uint32_t, const multiboot_info_t *); |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/include/drivers/kbd.h |
---|
File deleted |
/branches/dd/kernel/arch/ia32/include/drivers/ega.h |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32_EGA_H_ |
#define KERN_ia32_EGA_H_ |
#define VIDEORAM 0xb8000 |
#define ROW 80 |
#define ROWS 25 |
#define SCREEN (ROW * ROWS) |
extern void ega_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32/include/drivers/vesa.h |
---|
36,7 → 36,6 |
#define KERN_ia32_VESA_H_ |
extern int vesa_present(void); |
extern void vesa_redraw(void); |
extern void vesa_init(void); |
#endif |
/branches/dd/kernel/arch/ia32/include/drivers/i8259.h |
---|
38,10 → 38,10 |
#include <arch/types.h> |
#include <arch/interrupt.h> |
#define PIC_PIC0PORT1 ((ioport8_t *) 0x20) |
#define PIC_PIC0PORT2 ((ioport8_t *) 0x21) |
#define PIC_PIC1PORT1 ((ioport8_t *) 0xa0) |
#define PIC_PIC1PORT2 ((ioport8_t *) 0xa1) |
#define PIC_PIC0PORT1 0x20 |
#define PIC_PIC0PORT2 0x21 |
#define PIC_PIC1PORT1 0xa0 |
#define PIC_PIC1PORT2 0xa1 |
#define PIC_NEEDICW4 (1<<0) |
#define PIC_ICW1 (1<<4) |
/branches/dd/kernel/arch/ia32/include/drivers/i8042.h |
---|
0,0 → 1,71 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
*/ |
/** |
* This file implements ia32 specific access to i8042 registers. |
*/ |
#ifndef KERN_ia32_I8042_H_ |
#define KERN_ia32_I8042_H_ |
#include <arch/asm.h> |
#include <arch/types.h> |
#define i8042_DATA 0x60 |
#define i8042_STATUS 0x64 |
static inline void i8042_data_write(uint8_t data) |
{ |
outb(i8042_DATA, data); |
} |
static inline uint8_t i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline uint8_t i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(uint8_t command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32/src/syscall.c |
---|
File deleted |
/branches/dd/kernel/arch/ia32/src/asm.S |
---|
37,8 → 37,6 |
.global paging_on |
.global enable_l_apic_in_msr |
.global interrupt_handlers |
.global memsetb |
.global memsetw |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
46,15 → 44,6 |
.global memcpy_to_uspace_failover_address |
# Wrapper for generic memsetb |
memsetb: |
jmp _memsetb |
# Wrapper for generic memsetw |
memsetw: |
jmp _memsetw |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |
71,7 → 60,7 |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_DST(%esp) on success and 0 on failure. |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
96,7 → 85,7 |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_DST(%esp), %eax /* MEMCPY_DST(%esp), success */ |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
ret |
/* |
147,46 → 136,6 |
popfl |
.endm |
/* |
* The SYSENTER syscall mechanism can be used for syscalls with |
* four or fewer arguments. To pass these four arguments, we |
* use four registers: EDX, ECX, EBX, ESI. The syscall number |
* is passed in EAX. We use EDI to remember the return address |
* and EBP to remember the stack. The INT-based syscall mechanism |
* can actually handle six arguments plus the syscall number |
* entirely in registers. |
*/ |
.global sysenter_handler |
sysenter_handler: |
sti |
pushl %ebp # remember user stack |
pushl %edi # remember return user address |
pushl %gs # remember TLS |
pushl %eax # syscall number |
subl $8, %esp # unused sixth and fifth argument |
pushl %esi # fourth argument |
pushl %ebx # third argument |
pushl %ecx # second argument |
pushl %edx # first argument |
movw $16, %ax |
movw %ax, %ds |
movw %ax, %es |
cld |
call syscall_handler |
addl $28, %esp # remove arguments from stack |
pop %gs # restore TLS |
pop %edx # prepare return EIP for SYSEXIT |
pop %ecx # prepare userspace ESP for SYSEXIT |
sysexit # return to userspace |
## Declare interrupt handlers |
# |
# Declare interrupt handlers for n interrupt |
268,6 → 217,14 |
pushl %fs |
pushl %gs |
#ifdef CONFIG_DEBUG_ALLREGS |
pushl %ebx |
pushl %ebp |
pushl %edi |
pushl %esi |
#else |
subl $16, %esp |
#endif |
pushl %edx |
pushl %ecx |
pushl %eax |
289,6 → 246,14 |
popl %eax |
popl %ecx |
popl %edx |
#ifdef CONFIG_DEBUG_ALLREGS |
popl %esi |
popl %edi |
popl %ebp |
popl %ebx |
#else |
addl $16, %esp |
#endif |
popl %gs |
popl %fs |
/branches/dd/kernel/arch/ia32/src/boot/boot.S |
---|
101,18 → 101,117 |
shr $16, %ebx |
mov %bx, KA2PA(vesa_bpp) |
#endif |
call map_kernel # map kernel and turn paging on |
# arch_pre_main(grub_eax, grub_ebx) |
pushl grub_ebx |
pushl grub_eax |
call arch_pre_main |
call main_bsp |
movl grub_eax, %eax |
movl grub_ebx, %ebx |
cmpl $MULTIBOOT_LOADER_MAGIC, %eax # compare GRUB signature |
je valid_boot |
xorl %ecx, %ecx # no memory map available |
movl %ecx, e820counter |
jmp invalid_boot |
valid_boot: |
movl (%ebx), %eax # ebx = physical address of struct multiboot_info |
bt $3, %eax # mbi->flags[3] (mods_count, mods_addr valid) |
jc mods_valid |
xorl %ecx, %ecx |
movl %ecx, init |
jmp mods_end |
mods_valid: |
movl 20(%ebx), %ecx # mbi->mods_count |
movl %ecx, init |
cmpl $0, %ecx |
je mods_end |
movl 24(%ebx), %esi # mbi->mods_addr |
movl $init, %edi |
mods_loop: |
movl 0(%esi), %edx # mods->mod_start |
addl $0x80000000, %edx |
movl %edx, 4(%edi) |
movl 4(%esi), %edx |
subl 0(%esi), %edx # mods->mod_end - mods->mod_start |
movl %edx, 8(%edi) |
addl $16, %esi |
addl $8 , %edi |
loop mods_loop |
mods_end: |
bt $6, %eax # mbi->flags[6] (mmap_length, mmap_addr valid) |
jc mmap_valid |
xorl %edx, %edx |
jmp mmap_invalid |
mmap_valid: |
movl 44(%ebx), %ecx # mbi->mmap_length |
movl 48(%ebx), %esi # mbi->mmap_addr |
movl $e820table, %edi |
xorl %edx, %edx |
mmap_loop: |
cmpl $0, %ecx |
jle mmap_end |
movl 4(%esi), %eax # mmap->base_addr_low |
movl %eax, (%edi) |
movl 8(%esi), %eax # mmap->base_addr_high |
movl %eax, 4(%edi) |
movl 12(%esi), %eax # mmap->length_low |
movl %eax, 8(%edi) |
movl 16(%esi), %eax # mmap->length_high |
movl %eax, 12(%edi) |
movl 20(%esi), %eax # mmap->type |
movl %eax, 16(%edi) |
movl (%esi), %eax # mmap->size |
addl $0x4, %eax |
addl %eax, %esi |
subl %eax, %ecx |
addl $MEMMAP_E820_RECORD_SIZE, %edi |
incl %edx |
jmp mmap_loop |
mmap_end: |
mmap_invalid: |
movl %edx, e820counter |
invalid_boot: |
# Not reached. |
#ifdef CONFIG_SMP |
# copy AP bootstrap routines below 1 MB |
movl $BOOT_OFFSET, %esi |
movl $AP_BOOT_OFFSET, %edi |
movl $_hardcoded_unmapped_size, %ecx |
rep movsb |
#endif |
call main_bsp # never returns |
cli |
hlt |
343,8 → 442,7 |
xor %dx, %dx |
int $0x10 |
cmp $0x00, %ah |
je vga_not_compat |
jmp vga_not_compat |
vga_compat: |
/branches/dd/kernel/arch/ia32/src/boot/vga323.pal |
---|
1,256 → 1,256 |
.byte 0x00, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x3f, 0x00 |
.byte 0x36, 0x3f, 0x3f, 0x00 |
.byte 0x2d, 0x3f, 0x3f, 0x00 |
.byte 0x24, 0x3f, 0x3f, 0x00 |
.byte 0x1b, 0x3f, 0x3f, 0x00 |
.byte 0x12, 0x3f, 0x3f, 0x00 |
.byte 0x09, 0x3f, 0x3f, 0x00 |
.byte 0x00, 0x3f, 0x3f, 0x00 |
.byte 0x3f, 0x2a, 0x3f, 0x00 |
.byte 0x36, 0x2a, 0x3f, 0x00 |
.byte 0x2d, 0x2a, 0x3f, 0x00 |
.byte 0x24, 0x2a, 0x3f, 0x00 |
.byte 0x1b, 0x2a, 0x3f, 0x00 |
.byte 0x12, 0x2a, 0x3f, 0x00 |
.byte 0x09, 0x2a, 0x3f, 0x00 |
.byte 0x00, 0x2a, 0x3f, 0x00 |
.byte 0x3f, 0x15, 0x3f, 0x00 |
.byte 0x36, 0x15, 0x3f, 0x00 |
.byte 0x2d, 0x15, 0x3f, 0x00 |
.byte 0x24, 0x15, 0x3f, 0x00 |
.byte 0x1b, 0x15, 0x3f, 0x00 |
.byte 0x12, 0x15, 0x3f, 0x00 |
.byte 0x09, 0x15, 0x3f, 0x00 |
.byte 0x00, 0x15, 0x3f, 0x00 |
.byte 0x3f, 0x00, 0x3f, 0x00 |
.byte 0x36, 0x00, 0x3f, 0x00 |
.byte 0x2d, 0x00, 0x3f, 0x00 |
.byte 0x24, 0x00, 0x3f, 0x00 |
.byte 0x1b, 0x00, 0x3f, 0x00 |
.byte 0x12, 0x00, 0x3f, 0x00 |
.byte 0x09, 0x00, 0x3f, 0x00 |
.byte 0x00, 0x00, 0x3f, 0x00 |
.byte 0x3f, 0x3f, 0x36, 0x00 |
.byte 0x36, 0x3f, 0x36, 0x00 |
.byte 0x2d, 0x3f, 0x36, 0x00 |
.byte 0x24, 0x3f, 0x36, 0x00 |
.byte 0x1b, 0x3f, 0x36, 0x00 |
.byte 0x12, 0x3f, 0x36, 0x00 |
.byte 0x09, 0x3f, 0x36, 0x00 |
.byte 0x00, 0x3f, 0x36, 0x00 |
.byte 0x3f, 0x2a, 0x36, 0x00 |
.byte 0x36, 0x2a, 0x36, 0x00 |
.byte 0x2d, 0x2a, 0x36, 0x00 |
.byte 0x24, 0x2a, 0x36, 0x00 |
.byte 0x1b, 0x2a, 0x36, 0x00 |
.byte 0x12, 0x2a, 0x36, 0x00 |
.byte 0x09, 0x2a, 0x36, 0x00 |
.byte 0x00, 0x2a, 0x36, 0x00 |
.byte 0x3f, 0x15, 0x36, 0x00 |
.byte 0x36, 0x15, 0x36, 0x00 |
.byte 0x2d, 0x15, 0x36, 0x00 |
.byte 0x24, 0x15, 0x36, 0x00 |
.byte 0x1b, 0x15, 0x36, 0x00 |
.byte 0x12, 0x15, 0x36, 0x00 |
.byte 0x09, 0x15, 0x36, 0x00 |
.byte 0x00, 0x15, 0x36, 0x00 |
.byte 0x3f, 0x00, 0x36, 0x00 |
.byte 0x36, 0x00, 0x36, 0x00 |
.byte 0x2d, 0x00, 0x36, 0x00 |
.byte 0x24, 0x00, 0x36, 0x00 |
.byte 0x1b, 0x00, 0x36, 0x00 |
.byte 0x12, 0x00, 0x36, 0x00 |
.byte 0x09, 0x00, 0x36, 0x00 |
.byte 0x00, 0x00, 0x36, 0x00 |
.byte 0x3f, 0x3f, 0x2d, 0x00 |
.byte 0x36, 0x3f, 0x2d, 0x00 |
.byte 0x2d, 0x3f, 0x2d, 0x00 |
.byte 0x24, 0x3f, 0x2d, 0x00 |
.byte 0x1b, 0x3f, 0x2d, 0x00 |
.byte 0x12, 0x3f, 0x2d, 0x00 |
.byte 0x09, 0x3f, 0x2d, 0x00 |
.byte 0x00, 0x3f, 0x2d, 0x00 |
.byte 0x3f, 0x2a, 0x2d, 0x00 |
.byte 0x36, 0x2a, 0x2d, 0x00 |
.byte 0x2d, 0x2a, 0x2d, 0x00 |
.byte 0x24, 0x2a, 0x2d, 0x00 |
.byte 0x1b, 0x2a, 0x2d, 0x00 |
.byte 0x12, 0x2a, 0x2d, 0x00 |
.byte 0x09, 0x2a, 0x2d, 0x00 |
.byte 0x00, 0x2a, 0x2d, 0x00 |
.byte 0x3f, 0x15, 0x2d, 0x00 |
.byte 0x36, 0x15, 0x2d, 0x00 |
.byte 0x2d, 0x15, 0x2d, 0x00 |
.byte 0x24, 0x15, 0x2d, 0x00 |
.byte 0x1b, 0x15, 0x2d, 0x00 |
.byte 0x12, 0x15, 0x2d, 0x00 |
.byte 0x09, 0x15, 0x2d, 0x00 |
.byte 0x00, 0x15, 0x2d, 0x00 |
.byte 0x3f, 0x00, 0x2d, 0x00 |
.byte 0x36, 0x00, 0x2d, 0x00 |
.byte 0x2d, 0x00, 0x2d, 0x00 |
.byte 0x24, 0x00, 0x2d, 0x00 |
.byte 0x1b, 0x00, 0x2d, 0x00 |
.byte 0x12, 0x00, 0x2d, 0x00 |
.byte 0x09, 0x00, 0x2d, 0x00 |
.byte 0x00, 0x00, 0x2d, 0x00 |
.byte 0x3f, 0x3f, 0x24, 0x00 |
.byte 0x36, 0x3f, 0x24, 0x00 |
.byte 0x2d, 0x3f, 0x24, 0x00 |
.byte 0x24, 0x3f, 0x24, 0x00 |
.byte 0x1b, 0x3f, 0x24, 0x00 |
.byte 0x12, 0x3f, 0x24, 0x00 |
.byte 0x09, 0x3f, 0x24, 0x00 |
.byte 0x00, 0x3f, 0x24, 0x00 |
.byte 0x3f, 0x2a, 0x24, 0x00 |
.byte 0x36, 0x2a, 0x24, 0x00 |
.byte 0x2d, 0x2a, 0x24, 0x00 |
.byte 0x24, 0x2a, 0x24, 0x00 |
.byte 0x1b, 0x2a, 0x24, 0x00 |
.byte 0x12, 0x2a, 0x24, 0x00 |
.byte 0x09, 0x2a, 0x24, 0x00 |
.byte 0x00, 0x2a, 0x24, 0x00 |
.byte 0x3f, 0x15, 0x24, 0x00 |
.byte 0x36, 0x15, 0x24, 0x00 |
.byte 0x2d, 0x15, 0x24, 0x00 |
.byte 0x24, 0x15, 0x24, 0x00 |
.byte 0x1b, 0x15, 0x24, 0x00 |
.byte 0x12, 0x15, 0x24, 0x00 |
.byte 0x09, 0x15, 0x24, 0x00 |
.byte 0x00, 0x15, 0x24, 0x00 |
.byte 0x3f, 0x00, 0x24, 0x00 |
.byte 0x36, 0x00, 0x24, 0x00 |
.byte 0x2d, 0x00, 0x24, 0x00 |
.byte 0x24, 0x00, 0x24, 0x00 |
.byte 0x1b, 0x00, 0x24, 0x00 |
.byte 0x12, 0x00, 0x24, 0x00 |
.byte 0x09, 0x00, 0x24, 0x00 |
.byte 0x00, 0x00, 0x24, 0x00 |
.byte 0x3f, 0x3f, 0x1b, 0x00 |
.byte 0x36, 0x3f, 0x1b, 0x00 |
.byte 0x2d, 0x3f, 0x1b, 0x00 |
.byte 0x24, 0x3f, 0x1b, 0x00 |
.byte 0x1b, 0x3f, 0x1b, 0x00 |
.byte 0x12, 0x3f, 0x1b, 0x00 |
.byte 0x09, 0x3f, 0x1b, 0x00 |
.byte 0x00, 0x3f, 0x1b, 0x00 |
.byte 0x3f, 0x2a, 0x1b, 0x00 |
.byte 0x36, 0x2a, 0x1b, 0x00 |
.byte 0x2d, 0x2a, 0x1b, 0x00 |
.byte 0x24, 0x2a, 0x1b, 0x00 |
.byte 0x1b, 0x2a, 0x1b, 0x00 |
.byte 0x12, 0x2a, 0x1b, 0x00 |
.byte 0x09, 0x2a, 0x1b, 0x00 |
.byte 0x00, 0x2a, 0x1b, 0x00 |
.byte 0x3f, 0x15, 0x1b, 0x00 |
.byte 0x36, 0x15, 0x1b, 0x00 |
.byte 0x2d, 0x15, 0x1b, 0x00 |
.byte 0x24, 0x15, 0x1b, 0x00 |
.byte 0x1b, 0x15, 0x1b, 0x00 |
.byte 0x12, 0x15, 0x1b, 0x00 |
.byte 0x09, 0x15, 0x1b, 0x00 |
.byte 0x00, 0x15, 0x1b, 0x00 |
.byte 0x3f, 0x00, 0x1b, 0x00 |
.byte 0x36, 0x00, 0x1b, 0x00 |
.byte 0x2d, 0x00, 0x1b, 0x00 |
.byte 0x24, 0x00, 0x1b, 0x00 |
.byte 0x1b, 0x00, 0x1b, 0x00 |
.byte 0x12, 0x00, 0x1b, 0x00 |
.byte 0x09, 0x00, 0x1b, 0x00 |
.byte 0x00, 0x00, 0x1b, 0x00 |
.byte 0x3f, 0x3f, 0x12, 0x00 |
.byte 0x36, 0x3f, 0x12, 0x00 |
.byte 0x2d, 0x3f, 0x12, 0x00 |
.byte 0x24, 0x3f, 0x12, 0x00 |
.byte 0x1b, 0x3f, 0x12, 0x00 |
.byte 0x12, 0x3f, 0x12, 0x00 |
.byte 0x09, 0x3f, 0x12, 0x00 |
.byte 0x00, 0x3f, 0x12, 0x00 |
.byte 0x3f, 0x2a, 0x12, 0x00 |
.byte 0x36, 0x2a, 0x12, 0x00 |
.byte 0x2d, 0x2a, 0x12, 0x00 |
.byte 0x24, 0x2a, 0x12, 0x00 |
.byte 0x1b, 0x2a, 0x12, 0x00 |
.byte 0x12, 0x2a, 0x12, 0x00 |
.byte 0x09, 0x2a, 0x12, 0x00 |
.byte 0x00, 0x2a, 0x12, 0x00 |
.byte 0x3f, 0x15, 0x12, 0x00 |
.byte 0x36, 0x15, 0x12, 0x00 |
.byte 0x2d, 0x15, 0x12, 0x00 |
.byte 0x24, 0x15, 0x12, 0x00 |
.byte 0x1b, 0x15, 0x12, 0x00 |
.byte 0x12, 0x15, 0x12, 0x00 |
.byte 0x09, 0x15, 0x12, 0x00 |
.byte 0x00, 0x15, 0x12, 0x00 |
.byte 0x3f, 0x00, 0x12, 0x00 |
.byte 0x36, 0x00, 0x12, 0x00 |
.byte 0x2d, 0x00, 0x12, 0x00 |
.byte 0x24, 0x00, 0x12, 0x00 |
.byte 0x1b, 0x00, 0x12, 0x00 |
.byte 0x12, 0x00, 0x12, 0x00 |
.byte 0x09, 0x00, 0x12, 0x00 |
.byte 0x00, 0x00, 0x12, 0x00 |
.byte 0x3f, 0x3f, 0x09, 0x00 |
.byte 0x36, 0x3f, 0x09, 0x00 |
.byte 0x2d, 0x3f, 0x09, 0x00 |
.byte 0x24, 0x3f, 0x09, 0x00 |
.byte 0x1b, 0x3f, 0x09, 0x00 |
.byte 0x12, 0x3f, 0x09, 0x00 |
.byte 0x09, 0x3f, 0x09, 0x00 |
.byte 0x00, 0x3f, 0x09, 0x00 |
.byte 0x3f, 0x2a, 0x09, 0x00 |
.byte 0x36, 0x2a, 0x09, 0x00 |
.byte 0x2d, 0x2a, 0x09, 0x00 |
.byte 0x24, 0x2a, 0x09, 0x00 |
.byte 0x1b, 0x2a, 0x09, 0x00 |
.byte 0x12, 0x2a, 0x09, 0x00 |
.byte 0x09, 0x2a, 0x09, 0x00 |
.byte 0x00, 0x2a, 0x09, 0x00 |
.byte 0x3f, 0x15, 0x09, 0x00 |
.byte 0x36, 0x15, 0x09, 0x00 |
.byte 0x2d, 0x15, 0x09, 0x00 |
.byte 0x24, 0x15, 0x09, 0x00 |
.byte 0x1b, 0x15, 0x09, 0x00 |
.byte 0x12, 0x15, 0x09, 0x00 |
.byte 0x09, 0x15, 0x09, 0x00 |
.byte 0x00, 0x15, 0x09, 0x00 |
.byte 0x3f, 0x00, 0x09, 0x00 |
.byte 0x36, 0x00, 0x09, 0x00 |
.byte 0x2d, 0x00, 0x09, 0x00 |
.byte 0x24, 0x00, 0x09, 0x00 |
.byte 0x1b, 0x00, 0x09, 0x00 |
.byte 0x12, 0x00, 0x09, 0x00 |
.byte 0x09, 0x00, 0x09, 0x00 |
.byte 0x00, 0x00, 0x09, 0x00 |
.byte 0x3f, 0x3f, 0x00, 0x00 |
.byte 0x36, 0x3f, 0x00, 0x00 |
.byte 0x2d, 0x3f, 0x00, 0x00 |
.byte 0x24, 0x3f, 0x00, 0x00 |
.byte 0x1b, 0x3f, 0x00, 0x00 |
.byte 0x12, 0x3f, 0x00, 0x00 |
.byte 0x09, 0x3f, 0x00, 0x00 |
.byte 0x00, 0x3f, 0x00, 0x00 |
.byte 0x3f, 0x2a, 0x00, 0x00 |
.byte 0x36, 0x2a, 0x00, 0x00 |
.byte 0x2d, 0x2a, 0x00, 0x00 |
.byte 0x24, 0x2a, 0x00, 0x00 |
.byte 0x1b, 0x2a, 0x00, 0x00 |
.byte 0x12, 0x2a, 0x00, 0x00 |
.byte 0x09, 0x2a, 0x00, 0x00 |
.byte 0x00, 0x2a, 0x00, 0x00 |
.byte 0x3f, 0x15, 0x00, 0x00 |
.byte 0x36, 0x15, 0x00, 0x00 |
.byte 0x2d, 0x15, 0x00, 0x00 |
.byte 0x24, 0x15, 0x00, 0x00 |
.byte 0x1b, 0x15, 0x00, 0x00 |
.byte 0x12, 0x15, 0x00, 0x00 |
.byte 0x09, 0x15, 0x00, 0x00 |
.byte 0x00, 0x15, 0x00, 0x00 |
.byte 0x3f, 0x00, 0x00, 0x00 |
.byte 0x36, 0x00, 0x00, 0x00 |
.byte 0x2d, 0x00, 0x00, 0x00 |
.byte 0x24, 0x00, 0x00, 0x00 |
.byte 0x1b, 0x00, 0x00, 0x00 |
.byte 0x12, 0x00, 0x00, 0x00 |
.byte 0x09, 0x00, 0x00, 0x00 |
.byte 0x00, 0x00, 0x00, 0x00 |
/branches/dd/kernel/arch/ia32/src/ia32.c |
---|
1,7 → 1,5 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2009 Jiri Svoboda |
* Copyright (c) 2009 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
40,12 → 38,9 |
#include <arch/pm.h> |
#include <genarch/multiboot/multiboot.h> |
#include <genarch/drivers/legacy/ia32/io.h> |
#include <genarch/drivers/ega/ega.h> |
#include <arch/drivers/ega.h> |
#include <arch/drivers/vesa.h> |
#include <genarch/drivers/i8042/i8042.h> |
#include <genarch/kbrd/kbrd.h> |
#include <genarch/kbd/i8042.h> |
#include <arch/drivers/i8254.h> |
#include <arch/drivers/i8259.h> |
66,30 → 61,11 |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/device.h> |
#include <sysinfo/sysinfo.h> |
#include <arch/boot/boot.h> |
#ifdef CONFIG_SMP |
#include <arch/smp/apic.h> |
#endif |
/** Perform ia32-specific initialization before main_bsp() is called. |
* |
* @param signature Should contain the multiboot signature. |
* @param mi Pointer to the multiboot information structure. |
*/ |
void arch_pre_main(uint32_t signature, const multiboot_info_t *mi) |
{ |
/* Parse multiboot information obtained from the bootloader. */ |
multiboot_info_parse(signature, mi); |
#ifdef CONFIG_SMP |
/* Copy AP bootstrap routines below 1 MB. */ |
memcpy((void *) AP_BOOT_OFFSET, (void *) BOOT_OFFSET, |
(size_t) &_hardcoded_unmapped_size); |
#endif |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
117,7 → 93,7 |
vesa_init(); |
else |
#endif |
ega_init(EGA_BASE, EGA_VIDEORAM); /* video */ |
ega_init(); /* video */ |
/* Enable debugger */ |
debugger_init(); |
147,28 → 123,10 |
void arch_post_smp_init(void) |
{ |
devno_t devno = device_assign_devno(); |
/* |
* Initialize the keyboard module and conect it to stdin. Then |
* initialize the i8042 controller and connect it to kbrdin. Enable |
* keyboard interrupts. |
*/ |
kbrd_init(stdin); |
(void) i8042_init((i8042_t *) I8042_BASE, devno, IRQ_KBD, &kbrdin); |
trap_virtual_enable_irqs(1 << IRQ_KBD); |
/* |
* This is the necessary evil until the userspace driver is entirely |
* self-sufficient. |
*/ |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, IRQ_KBD); |
sysinfo_set_item_val("kbd.address.physical", NULL, |
(uintptr_t) I8042_BASE); |
sysinfo_set_item_val("kbd.address.kernel", NULL, |
(uintptr_t) I8042_BASE); |
devno_t kbd = device_assign_devno(); |
devno_t mouse = device_assign_devno(); |
/* keyboard controller */ |
i8042_init(kbd, IRQ_KBD, mouse, IRQ_MOUSE); |
} |
void calibrate_delay_loop(void) |
201,33 → 159,15 |
*/ |
void arch_grab_console(void) |
{ |
#ifdef CONFIG_FB |
vesa_redraw(); |
#else |
ega_redraw(); |
#endif |
i8042_grab(); |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
i8042_release(); |
} |
/** Construct function pointer |
* |
* @param fptr function pointer structure |
* @param addr function address |
* @param caller calling function address |
* |
* @return address of the function pointer |
* |
*/ |
void *arch_construct_function(fncptr_t *fptr, void *addr, void *caller) |
{ |
return addr; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32/src/mm/frame.c |
---|
54,57 → 54,26 |
static void init_e820_memory(pfn_t minconf) |
{ |
unsigned int i; |
pfn_t start, conf; |
size_t size; |
for (i = 0; i < e820counter; i++) { |
uint64_t base = e820table[i].base_address; |
uint64_t size = e820table[i].size; |
#ifdef __32_BITS__ |
/* Ignore physical memory above 4 GB */ |
if ((base >> 32) != 0) |
continue; |
/* Clip regions above 4 GB */ |
if (((base + size) >> 32) != 0) |
size = 0xffffffff - base; |
#endif |
pfn_t pfn; |
count_t count; |
if (e820table[i].type == MEMMAP_MEMORY_AVAILABLE) { |
/* To be safe, make available zone possibly smaller */ |
pfn = ADDR2PFN(ALIGN_UP(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_DOWN(size, FRAME_SIZE)); |
start = ADDR2PFN(ALIGN_UP(e820table[i].base_address, FRAME_SIZE)); |
size = SIZE2FRAMES(ALIGN_DOWN(e820table[i].size, FRAME_SIZE)); |
pfn_t conf; |
if ((minconf < pfn) || (minconf >= pfn + count)) |
conf = pfn; |
if ((minconf < start) || (minconf >= start + size)) |
conf = start; |
else |
conf = minconf; |
zone_create(pfn, count, conf, ZONE_AVAILABLE); |
zone_create(start, size, conf, 0); |
// XXX this has to be removed |
if (last_frame < ALIGN_UP(base + size, FRAME_SIZE)) |
last_frame = ALIGN_UP(base + size, FRAME_SIZE); |
} |
if (e820table[i].type == MEMMAP_MEMORY_RESERVED) { |
/* To be safe, make reserved zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_RESERVED); |
} |
if (e820table[i].type == MEMMAP_MEMORY_ACPI) { |
/* To be safe, make firmware zone possibly larger */ |
pfn = ADDR2PFN(ALIGN_DOWN(base, (uintptr_t) FRAME_SIZE)); |
count = SIZE2FRAMES(ALIGN_UP(size, (uintptr_t) FRAME_SIZE)); |
zone_create(pfn, count, 0, ZONE_FIRMWARE); |
} |
if (last_frame < ALIGN_UP(e820table[i].base_address + |
e820table[i].size, FRAME_SIZE)) |
last_frame = |
ALIGN_UP(e820table[i].base_address + e820table[i].size, FRAME_SIZE); |
} |
} |
} |
144,14 → 113,16 |
if (config.cpu_active == 1) { |
minconf = 1; |
#ifdef CONFIG_SMP |
minconf = max(minconf, |
ADDR2PFN(AP_BOOT_OFFSET + hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size)); |
#endif |
#ifdef CONFIG_SIMICS_FIX |
minconf = max(minconf, ADDR2PFN(0x10000)); |
#endif |
init_e820_memory(minconf); |
/* Reserve frame 0 (BIOS data) */ |
frame_mark_unavailable(0, 1); |
160,7 → 131,12 |
frame_mark_unavailable(AP_BOOT_OFFSET >> FRAME_WIDTH, |
(hardcoded_unmapped_ktext_size + |
hardcoded_unmapped_kdata_size) >> FRAME_WIDTH); |
#ifdef CONFIG_SIMICS_FIX |
/* Don't know why, but these addresses help */ |
frame_mark_unavailable(0xd000 >> FRAME_WIDTH, 3); |
#endif |
#endif |
} |
} |
/branches/dd/kernel/arch/ia32/src/mm/page.c |
---|
53,7 → 53,7 |
{ |
uintptr_t cur; |
int flags; |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
66,12 → 66,12 |
flags |= PAGE_GLOBAL; |
page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags); |
} |
exc_register(14, "page_fault", (iroutine) page_fault); |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
} else |
write_cr3((uintptr_t) AS_KERNEL->genarch.page_table); |
paging_on(); |
} |
79,7 → 79,7 |
uintptr_t hw_map(uintptr_t physaddr, size_t size) |
{ |
if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH)) |
panic("Unable to map physical memory %p (%d bytes).", physaddr, size) |
panic("Unable to map physical memory %p (%d bytes)", physaddr, size) |
uintptr_t virtaddr = PA2KA(last_frame); |
pfn_t i; |
101,8 → 101,8 |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory."); |
panic("Reserved bit set in page directory.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
109,11 → 109,11 |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x.", page); |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(istate); |
printf("page fault address: %#lx\n", page); |
panic("Page fault."); |
panic("page fault\n"); |
} |
} |
/branches/dd/kernel/arch/ia32/src/mm/tlb.c |
---|
67,13 → 67,5 |
invlpg(page + i * PAGE_SIZE); |
} |
void tlb_arch_init(void) |
{ |
} |
void tlb_print(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32/src/mm/as.c |
---|
39,7 → 39,9 |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
#ifndef __OBJC__ |
as_operations = &as_pt_operations; |
#endif |
} |
/** @} |
/branches/dd/kernel/arch/ia32/src/smp/smp.c |
---|
75,12 → 75,12 |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("Cannot allocate address for l_apic."); |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, |
FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("Cannot allocate address for io_apic."); |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, |
122,8 → 122,8 |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
pio_write_8((ioport8_t *)0x70, 0xf); |
pio_write_8((ioport8_t *)0x71, 0xa); |
outb(0x70, 0xf); |
outb(0x71, 0xa); |
pic_disable_irqs(0xffff); |
apic_init(); |
154,18 → 154,14 |
/* |
* Prepare new GDT for CPU in question. |
*/ |
/* XXX Flag FRAME_LOW_4_GiB was removed temporarily, |
* it needs to be replaced by a generic fuctionality of |
* the memory subsystem |
*/ |
gdt_new = (struct descriptor *) malloc(GDT_ITEMS * |
sizeof(struct descriptor), FRAME_ATOMIC); |
if (!gdt_new) |
panic("Cannot allocate memory for GDT."); |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb(&gdt_new[TSS_DES], sizeof(struct descriptor), 0); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), |
sizeof(struct descriptor), 0); |
protected_ap_gdtr.limit = GDT_ITEMS * sizeof(struct descriptor); |
protected_ap_gdtr.base = KA2PA((uintptr_t) gdt_new); |
gdtr.base = (uintptr_t) gdt_new; |
/branches/dd/kernel/arch/ia32/src/smp/apic.c |
---|
132,12 → 132,12 |
#endif |
} |
static irq_ownership_t l_apic_timer_claim(irq_t *irq) |
static irq_ownership_t l_apic_timer_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void l_apic_timer_irq_handler(irq_t *irq) |
static void l_apic_timer_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
{ |
/* |
* Holding a spinlock could prevent clock() from preempting |
/branches/dd/kernel/arch/ia32/src/smp/ap.S |
---|
45,7 → 45,7 |
KTEXT=8 |
KDATA=16 |
# This piece of code is real-mode and is meant to be aligned at 4K boundary. |
# This piece of code is real-mode and is meant to be alligned at 4K boundary. |
# The requirement for such an alignment comes from MP Specification's STARTUP IPI |
# requirements. |
/branches/dd/kernel/arch/ia32/src/proc/scheduler.c |
---|
38,6 → 38,7 |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
57,18 → 58,21 |
*/ |
void before_thread_runs_arch(void) |
{ |
uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE - |
SP_DELTA]; |
/* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */ |
write_msr(IA32_MSR_SYSENTER_ESP, kstk); |
/* Set kernel stack for CPL3 -> CPL0 switch via interrupt */ |
CPU->arch.tss->esp0 = kstk; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) { |
the_t *the = THE; |
breakpoint_add(&((the_t *) the->thread->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, the->cpu->id); |
} |
#endif |
} |
void after_thread_ran_arch(void) |
/branches/dd/kernel/arch/ia32/src/pm.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
112,7 → 112,7 |
void tss_initialize(tss_t *t) |
{ |
memsetb(t, sizeof(struct tss), 0); |
memsetb((uintptr_t) t, sizeof(struct tss), 0); |
} |
/* |
154,7 → 154,7 |
"and $0xffff8fff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
::: "eax" |
: : : "eax" |
); |
} |
165,7 → 165,7 |
"mov %%cr0, %%eax\n" |
"and $0xfffbffff, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "eax" |
: : : "eax" |
); |
} |
198,7 → 198,7 |
else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("Cannot allocate TSS."); |
panic("could not allocate TSS\n"); |
} |
tss_initialize(tss_p); |
240,7 → 240,7 |
preemption_disable(); |
ipl_t ipl = interrupts_disable(); |
memsetb(idt, sizeof(idt), 0); |
memsetb((uintptr_t) idt, sizeof(idt), 0); |
ptr_16_32_t idtr; |
idtr.limit = sizeof(idt); |
/branches/dd/kernel/arch/ia32/src/userspace.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
/** @addtogroup ia32 |
* @{ |
*/ |
/** @file |
47,8 → 47,10 |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
ipl_t ipl = interrupts_disable(); |
ipl_t ipl; |
ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
58,33 → 60,31 |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %[tls_des], %%gs\n" |
"pushl %[udata_des]\n" |
"pushl %[stack_size]\n" |
"pushl %[ipl]\n" |
"pushl %[utext_des]\n" |
"pushl %[entry]\n" |
"movl %[uarg], %%eax\n" |
/* %ebx is defined to hold pcb_ptr - set it to 0 */ |
"xorl %%ebx, %%ebx\n" |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"iret\n" |
: |
: [udata_des] "i" (selector(UDATA_DES) | PL_USER), |
[stack_size] "r" ((uint8_t *) kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
[ipl] "r" (ipl), |
[utext_des] "i" (selector(UTEXT_DES) | PL_USER), |
[entry] "r" (kernel_uarg->uspace_entry), |
[uarg] "r" (kernel_uarg->uspace_uarg), |
[tls_des] "r" (selector(TLS_DES)) |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" ((uint8_t *) kernel_uarg->uspace_stack + |
THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax"); |
/* Unreachable */ |
while (1); |
for(;;) |
; |
} |
/** @} |
/branches/dd/kernel/arch/ia32/src/interrupt.c |
---|
77,6 → 77,9 |
printf("ERROR_WORD=%#lx\n", istate->error_word); |
printf("%%cs=%#lx,flags=%#lx\n", istate->cs, istate->eflags); |
printf("%%eax=%#lx, %%ecx=%#lx, %%edx=%#lx, %%esp=%p\n", istate->eax, istate->ecx, istate->edx, &istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#lx, %%edi=%#lx, %%ebp=%#lx, %%ebx=%#lx\n", istate->esi, istate->edi, istate->ebp, istate->ebx); |
#endif |
printf("stack: %#lx, %#lx, %#lx, %#lx\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#lx, %#lx, %#lx, %#lx\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
86,16 → 89,16 |
if (eoi_function) |
eoi_function(); |
else |
panic("No eoi_function."); |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(istate); |
panic("Unserviced interrupt: %d.", n); |
panic("unserviced interrupt: %d\n", n); |
} |
/** General Protection Fault. */ |
119,19 → 122,19 |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "General protection fault."); |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(istate); |
panic("General protection fault."); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n __attribute__((unused)), istate_t *istate) |
{ |
fault_if_from_uspace(istate, "Stack fault."); |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(istate); |
panic("Stack fault."); |
panic("stack fault\n"); |
} |
static void simd_fp_exception(int n __attribute__((unused)), istate_t *istate) |
138,15 → 141,15 |
{ |
uint32_t mxcsr; |
asm ( |
"stmxcsr %[mxcsr]\n" |
: [mxcsr] "=m" (mxcsr) |
"stmxcsr %0;\n" |
: "=m" (mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
(unative_t) mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#lx\n", mxcsr); |
panic("SIMD FP exception(19)."); |
panic("SIMD FP exception(19)\n"); |
} |
static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
154,8 → 157,8 |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "FPU fault."); |
panic("FPU fault."); |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
188,7 → 191,7 |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq); |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
230,7 → 233,7 |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("No enable_irqs_function."); |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
238,7 → 241,7 |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("No disable_irqs_function."); |
panic("no disable_irqs_function\n"); |
} |
/** @} |
/branches/dd/kernel/arch/ia32/src/drivers/i8259.c |
---|
49,28 → 49,28 |
void i8259_init(void) |
{ |
/* ICW1: this is ICW1, ICW4 to follow */ |
pio_write_8(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
outb(PIC_PIC0PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 0 maps to INT IRQBASE */ |
pio_write_8(PIC_PIC0PORT2, IVT_IRQBASE); |
outb(PIC_PIC0PORT2, IVT_IRQBASE); |
/* ICW3: pic1 using IRQ IRQ_PIC1 */ |
pio_write_8(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
outb(PIC_PIC0PORT2, 1 << IRQ_PIC1); |
/* ICW4: i8086 mode */ |
pio_write_8(PIC_PIC0PORT2, 1); |
outb(PIC_PIC0PORT2, 1); |
/* ICW1: ICW1, ICW4 to follow */ |
pio_write_8(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
outb(PIC_PIC1PORT1, PIC_ICW1 | PIC_NEEDICW4); |
/* ICW2: IRQ 8 maps to INT (IVT_IRQBASE + 8) */ |
pio_write_8(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
outb(PIC_PIC1PORT2, IVT_IRQBASE + 8); |
/* ICW3: pic1 is known as IRQ_PIC1 */ |
pio_write_8(PIC_PIC1PORT2, IRQ_PIC1); |
outb(PIC_PIC1PORT2, IRQ_PIC1); |
/* ICW4: i8086 mode */ |
pio_write_8(PIC_PIC1PORT2, 1); |
outb(PIC_PIC1PORT2, 1); |
/* |
* Register interrupt handler for the PIC spurious interrupt. |
94,12 → 94,12 |
uint8_t x; |
if (irqmask & 0xff) { |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x & (~(irqmask & 0xff)))); |
} |
if (irqmask >> 8) { |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x & (~(irqmask >> 8)))); |
} |
} |
108,19 → 108,19 |
uint8_t x; |
if (irqmask & 0xff) { |
x = pio_read_8(PIC_PIC0PORT2); |
pio_write_8(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
x = inb(PIC_PIC0PORT2); |
outb(PIC_PIC0PORT2, (uint8_t) (x | (irqmask & 0xff))); |
} |
if (irqmask >> 8) { |
x = pio_read_8(PIC_PIC1PORT2); |
pio_write_8(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
x = inb(PIC_PIC1PORT2); |
outb(PIC_PIC1PORT2, (uint8_t) (x | (irqmask >> 8))); |
} |
} |
void pic_eoi(void) |
{ |
pio_write_8((ioport8_t *)0x20, 0x20); |
pio_write_8((ioport8_t *)0xa0, 0x20); |
outb(0x20, 0x20); |
outb(0xa0, 0x20); |
} |
void pic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) |
/branches/dd/kernel/arch/ia32/src/drivers/i8254.c |
---|
53,8 → 53,8 |
#include <ddi/irq.h> |
#include <ddi/device.h> |
#define CLK_PORT1 ((ioport8_t *)0x40) |
#define CLK_PORT4 ((ioport8_t *)0x43) |
#define CLK_PORT1 0x40 |
#define CLK_PORT4 0x43 |
#define CLK_CONST 1193180 |
#define MAGIC_NUMBER 1194 |
61,12 → 61,12 |
static irq_t i8254_irq; |
static irq_ownership_t i8254_claim(irq_t *irq) |
static irq_ownership_t i8254_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void i8254_irq_handler(irq_t *irq) |
static void i8254_irq_handler(irq_t *irq, void *arg __attribute__((unused)), ...) |
{ |
/* |
* This IRQ is responsible for kernel preemption. |
94,10 → 94,10 |
void i8254_normal_operation(void) |
{ |
pio_write_8(CLK_PORT4, 0x36); |
outb(CLK_PORT4, 0x36); |
pic_disable_irqs(1 << IRQ_CLK); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
pio_write_8(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
outb(CLK_PORT1, (CLK_CONST / HZ) & 0xf); |
outb(CLK_PORT1, (CLK_CONST / HZ) >> 8); |
pic_enable_irqs(1 << IRQ_CLK); |
} |
114,36 → 114,36 |
* One-shot timer. Count-down from 0xffff at 1193180Hz |
* MAGIC_NUMBER is the magic value for 1ms. |
*/ |
pio_write_8(CLK_PORT4, 0x30); |
pio_write_8(CLK_PORT1, 0xff); |
pio_write_8(CLK_PORT1, 0xff); |
outb(CLK_PORT4, 0x30); |
outb(CLK_PORT1, 0xff); |
outb(CLK_PORT1, 0xff); |
do { |
/* will read both status and count */ |
pio_write_8(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((pio_read_8(CLK_PORT1) >> 6) & 1); |
t1 = pio_read_8(CLK_PORT1); |
t1 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xc2); |
not_ok = (uint8_t) ((inb(CLK_PORT1) >> 6) & 1); |
t1 = inb(CLK_PORT1); |
t1 |= inb(CLK_PORT1) << 8; |
} while (not_ok); |
asm_delay_loop(LOOPS); |
pio_write_8(CLK_PORT4, 0xd2); |
t2 = pio_read_8(CLK_PORT1); |
t2 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
t2 = inb(CLK_PORT1); |
t2 |= inb(CLK_PORT1) << 8; |
/* |
* We want to determine the overhead of the calibrating mechanism. |
*/ |
pio_write_8(CLK_PORT4, 0xd2); |
o1 = pio_read_8(CLK_PORT1); |
o1 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
o1 = inb(CLK_PORT1); |
o1 |= inb(CLK_PORT1) << 8; |
asm_fake_loop(LOOPS); |
pio_write_8(CLK_PORT4, 0xd2); |
o2 = pio_read_8(CLK_PORT1); |
o2 |= pio_read_8(CLK_PORT1) << 8; |
outb(CLK_PORT4, 0xd2); |
o2 = inb(CLK_PORT1); |
o2 |= inb(CLK_PORT1) << 8; |
CPU->delay_loop_const = |
((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + |
/branches/dd/kernel/arch/ia32/src/drivers/ega.c |
---|
0,0 → 1,161 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32 |
* @{ |
*/ |
/** |
* @file |
* @brief EGA driver. |
*/ |
#include <arch/drivers/ega.h> |
#include <putchar.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/mm/page.h> |
#include <synch/spinlock.h> |
#include <arch/types.h> |
#include <arch/asm.h> |
#include <memstr.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <ddi/ddi.h> |
/* |
* The EGA driver. |
* Simple and short. Function for displaying characters and "scrolling". |
*/ |
static parea_t ega_parea; /**< Physical memory area for EGA video RAM. */ |
SPINLOCK_INITIALIZE(egalock); |
static uint32_t ega_cursor; |
static uint8_t *videoram; |
static void ega_putchar(chardev_t *d, const char ch); |
chardev_t ega_console; |
static chardev_operations_t ega_ops = { |
.write = ega_putchar |
}; |
static void ega_move_cursor(void); |
void ega_init(void) |
{ |
uint8_t hi, lo; |
videoram = (uint8_t *) hw_map(VIDEORAM, SCREEN * 2); |
outb(0x3d4, 0xe); |
hi = inb(0x3d5); |
outb(0x3d4, 0xf); |
lo = inb(0x3d5); |
ega_cursor = (hi << 8) | lo; |
chardev_initialize("ega_out", &ega_console, &ega_ops); |
stdout = &ega_console; |
ega_parea.pbase = VIDEORAM; |
ega_parea.vbase = (uintptr_t) videoram; |
ega_parea.frames = 1; |
ega_parea.cacheable = false; |
ddi_parea_register(&ega_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 2); |
sysinfo_set_item_val("fb.width", NULL, ROW); |
sysinfo_set_item_val("fb.height", NULL, ROWS); |
sysinfo_set_item_val("fb.address.physical", NULL, VIDEORAM); |
sysinfo_set_item_val("fb.address.color", NULL, PAGE_COLOR((uintptr_t) |
videoram)); |
#ifndef CONFIG_FB |
putchar('\n'); |
#endif |
} |
static void ega_display_char(char ch) |
{ |
videoram[ega_cursor * 2] = ch; |
} |
/* |
* This function takes care of scrolling. |
*/ |
static void ega_check_cursor(void) |
{ |
if (ega_cursor < SCREEN) |
return; |
memcpy((void *) videoram, (void *) (videoram + ROW * 2), (SCREEN - ROW) * 2); |
memsetw((uintptr_t) (videoram + (SCREEN - ROW) * 2), ROW, 0x0720); |
ega_cursor = ega_cursor - ROW; |
} |
void ega_putchar(chardev_t *d __attribute__((unused)), const char ch) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&egalock); |
switch (ch) { |
case '\n': |
ega_cursor = (ega_cursor + ROW) - ega_cursor % ROW; |
break; |
case '\t': |
ega_cursor = (ega_cursor + 8) - ega_cursor % 8; |
break; |
case '\b': |
if (ega_cursor % ROW) |
ega_cursor--; |
break; |
default: |
ega_display_char(ch); |
ega_cursor++; |
break; |
} |
ega_check_cursor(); |
ega_move_cursor(); |
spinlock_unlock(&egalock); |
interrupts_restore(ipl); |
} |
void ega_move_cursor(void) |
{ |
outb(0x3d4, 0xe); |
outb(0x3d5, (uint8_t) ((ega_cursor >> 8) & 0xff)); |
outb(0x3d4, 0xf); |
outb(0x3d5, (uint8_t) (ega_cursor & 0xff)); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32/src/drivers/vesa.c |
---|
83,25 → 83,12 |
visual = VISUAL_RGB_0_8_8_8; |
break; |
default: |
panic("Unsupported bits per pixel."); |
panic("Unsupported bits per pixel"); |
} |
fb_properties_t vesa_props = { |
.addr = vesa_ph_addr, |
.offset = 0, |
.x = vesa_width, |
.y = vesa_height, |
.scan = vesa_scanline, |
.visual = visual, |
}; |
fb_init(&vesa_props); |
fb_init(vesa_ph_addr, vesa_width, vesa_height, vesa_scanline, visual); |
} |
void vesa_redraw(void) |
{ |
fb_redraw(); |
} |
#endif |
/** @} |
/branches/dd/kernel/arch/ia32/src/cpu/cpu.c |
---|
42,23 → 42,22 |
#include <fpu_context.h> |
#include <arch/smp/apic.h> |
#include <arch/syscall.h> |
/* |
* Identification of CPUs. |
* Contains only non-MP-Specification specific SMP code. |
*/ |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define AMD_CPUID_EBX 0x68747541 |
#define AMD_CPUID_ECX 0x444d4163 |
#define AMD_CPUID_EDX 0x69746e65 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
#define INTEL_CPUID_EBX 0x756e6547 |
#define INTEL_CPUID_ECX 0x6c65746e |
#define INTEL_CPUID_EDX 0x49656e69 |
enum vendor { |
VendorUnknown = 0, |
VendorUnknown=0, |
VendorAMD, |
VendorIntel |
}; |
65,17 → 64,19 |
static char *vendor_str[] = { |
"Unknown Vendor", |
"AMD", |
"Intel" |
"AuthenticAMD", |
"GenuineIntel" |
}; |
void fpu_disable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%eax\n" |
"or $8, %%eax\n" |
"mov %%eax, %%cr0\n" |
::: "%eax" |
"mov %%cr0,%%eax;" |
"or $8,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
} |
82,11 → 83,13 |
void fpu_enable(void) |
{ |
asm volatile ( |
"mov %%cr0, %%eax\n" |
"and $0xffFFffF7, %%eax\n" |
"mov %%eax,%%cr0\n" |
::: "%eax" |
); |
"mov %%cr0,%%eax;" |
"and $0xffFFffF7,%%eax;" |
"mov %%eax,%%cr0;" |
: |
: |
:"%eax" |
); |
} |
void cpu_arch_init(void) |
98,11 → 101,11 |
CPU->arch.tss = tss_p; |
CPU->arch.tss->iomap_base = &CPU->arch.tss->iomap[0] - ((uint8_t *) CPU->arch.tss); |
CPU->fpu_owner = NULL; |
cpuid(1, &info); |
fi.word = info.cpuid_edx; |
efi.word = info.cpuid_ecx; |
109,20 → 112,17 |
if (fi.bits.fxsr) |
fpu_fxsr(); |
else |
fpu_fsr(); |
fpu_fsr(); |
if (fi.bits.sse) { |
asm volatile ( |
"mov %%cr4, %[help]\n" |
"or %[mask], %[help]\n" |
"mov %[help], %%cr4\n" |
: [help] "+r" (help) |
: [mask] "i" (CR4_OSFXSR_MASK | (1 << 10)) |
"mov %%cr4,%0\n" |
"or %1,%0\n" |
"mov %0,%%cr4\n" |
: "+r" (help) |
: "i" (CR4_OSFXSR_MASK|(1<<10)) |
); |
} |
/* Setup fast SYSENTER/SYSEXIT syscalls */ |
syscall_setup_cpu(); |
} |
void cpu_identify(void) |
136,31 → 136,29 |
/* |
* Check for AMD processor. |
*/ |
if ((info.cpuid_ebx == AMD_CPUID_EBX) |
&& (info.cpuid_ecx == AMD_CPUID_ECX) |
&& (info.cpuid_edx == AMD_CPUID_EDX)) |
if (info.cpuid_ebx==AMD_CPUID_EBX && info.cpuid_ecx==AMD_CPUID_ECX && info.cpuid_edx==AMD_CPUID_EDX) { |
CPU->arch.vendor = VendorAMD; |
} |
/* |
* Check for Intel processor. |
*/ |
if ((info.cpuid_ebx == INTEL_CPUID_EBX) |
&& (info.cpuid_ecx == INTEL_CPUID_ECX) |
&& (info.cpuid_edx == INTEL_CPUID_EDX)) |
if (info.cpuid_ebx==INTEL_CPUID_EBX && info.cpuid_ecx==INTEL_CPUID_ECX && info.cpuid_edx==INTEL_CPUID_EDX) { |
CPU->arch.vendor = VendorIntel; |
} |
cpuid(1, &info); |
CPU->arch.family = (info.cpuid_eax >> 8) & 0x0f; |
CPU->arch.model = (info.cpuid_eax >> 4) & 0x0f; |
CPU->arch.stepping = (info.cpuid_eax >> 0) & 0x0f; |
CPU->arch.family = (info.cpuid_eax>>8)&0xf; |
CPU->arch.model = (info.cpuid_eax>>4)&0xf; |
CPU->arch.stepping = (info.cpuid_eax>>0)&0xf; |
} |
} |
void cpu_print_report(cpu_t* cpu) |
void cpu_print_report(cpu_t* m) |
{ |
printf("cpu%u: (%s family=%u model=%u stepping=%u) %" PRIu16 " MHz\n", |
cpu->id, vendor_str[cpu->arch.vendor], cpu->arch.family, |
cpu->arch.model, cpu->arch.stepping, cpu->frequency_mhz); |
printf("cpu%d: (%s family=%d model=%d stepping=%d) %dMHz\n", |
m->id, vendor_str[m->arch.vendor], m->arch.family, m->arch.model, m->arch.stepping, |
m->frequency_mhz); |
} |
/** @} |
/branches/dd/kernel/arch/ia32/src/fpu_context.c |
---|
44,43 → 44,46 |
static void fpu_context_f_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fnsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fnsave %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_f_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"frstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"frstor %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_fx_save(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxsave %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fxsave %0" |
: "=m"(*fctx) |
); |
} |
static void fpu_context_fx_restore(fpu_context_t *fctx) |
{ |
asm volatile ( |
"fxrstor %[fctx]" |
: [fctx] "=m" (*fctx) |
); |
"fxrstor %0" |
: "=m"(*fctx) |
); |
} |
/* Setup using fxsr instruction */ |
/* |
Setup using fxsr instruction |
*/ |
void fpu_fxsr(void) |
{ |
fpu_save=fpu_context_fx_save; |
fpu_restore=fpu_context_fx_restore; |
} |
/* Setup using not fxsr instruction */ |
/* |
Setup using not fxsr instruction |
*/ |
void fpu_fsr(void) |
{ |
fpu_save = fpu_context_f_save; |
99,18 → 102,16 |
void fpu_init() |
{ |
uint32_t help0 = 0; |
uint32_t help1 = 0; |
uint32_t help0 = 0, help1 = 0; |
asm volatile ( |
"fninit\n" |
"stmxcsr %[help0]\n" |
"mov %[help0], %[help1]\n" |
"or %[magic], %[help1]\n" |
"mov %[help1], %[help0]\n" |
"ldmxcsr %[help0]\n" |
: [help0] "+m" (help0), [help1] "+r" (help1) |
: [magic] "i" (0x1f80) |
"fninit;\n" |
"stmxcsr %0\n" |
"mov %0,%1;\n" |
"or %2,%1;\n" |
"mov %1,%0;\n" |
"ldmxcsr %0;\n" |
: "+m" (help0), "+r" (help1) |
: "i" (0x1f80) |
); |
} |
/branches/dd/kernel/arch/ia32/src/debug/panic.s |
---|
30,5 → 30,5 |
.global panic_printf |
panic_printf: |
movl $halt, (%esp) # fake stack to make printf return to halt |
movl $halt,(%esp) # fake stack to make printf return to halt |
jmp printf |
/branches/dd/kernel/arch/ia32/Makefile.inc |
---|
33,9 → 33,9 |
BFD_ARCH = i386 |
BFD = binary |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686 |
TOOLCHAIN_DIR = /usr/local/i686 |
DEFS += -D__32_BITS__ |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
CMN1 = -m32 |
GCC_CFLAGS += $(CMN1) |
45,61 → 45,110 |
## Accepted CPUs |
# |
ifeq ($(PROCESSOR),athlon_xp) |
CMN2 = -march=athlon-xp |
ifeq ($(MACHINE),athlon-xp) |
CMN2 = -march=athlon-xp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),athlon_mp) |
CMN2 = -march=athlon-mp |
ifeq ($(MACHINE),athlon-mp) |
CMN2 = -march=athlon-mp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),pentium3) |
CMN2 = -march=pentium3 |
ifeq ($(MACHINE),pentium3) |
CMN2 = -march=pentium3 -mmmx -msse |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(PROCESSOR),pentium4) |
CMN2 = -march=pentium4 |
ifeq ($(MACHINE),core) |
CMN2 = -march=prescott -mfpmath=sse -mmmx -msse -msse2 -msse3 |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(MACHINE),pentium4) |
GCC_CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 |
ICC_CFLAGS += -march=pentium4 |
SUNCC_CFLAGS += -xarch=sse2 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(PROCESSOR),core) |
CMN2 = -march=prescott |
SUNCC_CFLAGS += -xarch=sse3 |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Compile with i8042 controller support |
# |
CONFIG_I8042 = y |
DEFS += -DCONFIG_I8042 |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
ifeq ($(CONFIG_SIMICS_FIX),y) |
DEFS += -DCONFIG_SIMICS_FIX |
endif |
FPU_NO_CFLAGS = -mno-mmx -mno-sse -mno-sse2 -mno-sse3 -mno-3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(KARCH)/src/context.S \ |
arch/$(KARCH)/src/debug/panic.s \ |
arch/$(KARCH)/src/delay.s \ |
arch/$(KARCH)/src/asm.S \ |
arch/$(KARCH)/src/proc/scheduler.c \ |
arch/$(KARCH)/src/proc/task.c \ |
arch/$(KARCH)/src/proc/thread.c \ |
arch/$(KARCH)/src/bios/bios.c \ |
arch/$(KARCH)/src/smp/ap.S \ |
arch/$(KARCH)/src/smp/apic.c \ |
arch/$(KARCH)/src/smp/mps.c \ |
arch/$(KARCH)/src/smp/smp.c \ |
arch/$(KARCH)/src/atomic.S \ |
arch/$(KARCH)/src/smp/ipi.c \ |
arch/$(KARCH)/src/ia32.c \ |
arch/$(KARCH)/src/interrupt.c \ |
arch/$(KARCH)/src/pm.c \ |
arch/$(KARCH)/src/userspace.c \ |
arch/$(KARCH)/src/cpu/cpu.c \ |
arch/$(KARCH)/src/mm/as.c \ |
arch/$(KARCH)/src/mm/frame.c \ |
arch/$(KARCH)/src/mm/page.c \ |
arch/$(KARCH)/src/mm/tlb.c \ |
arch/$(KARCH)/src/ddi/ddi.c \ |
arch/$(KARCH)/src/drivers/i8254.c \ |
arch/$(KARCH)/src/drivers/i8259.c \ |
arch/$(KARCH)/src/drivers/vesa.c \ |
arch/$(KARCH)/src/boot/boot.S \ |
arch/$(KARCH)/src/boot/memmap.c \ |
arch/$(KARCH)/src/fpu_context.c \ |
arch/$(KARCH)/src/debugger.c \ |
arch/$(KARCH)/src/syscall.c |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/delay.s \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/smp/ap.S \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/atomic.S \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/ia32.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/i8254.c \ |
arch/$(ARCH)/src/drivers/i8259.c \ |
arch/$(ARCH)/src/drivers/ega.c \ |
arch/$(ARCH)/src/drivers/vesa.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/boot/memmap.c \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
/branches/dd/kernel/arch/ia32/_link.ld.in |
---|
1,11 → 1,11 |
/** IA-32 linker script |
* |
* |
* umapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
* mapped section: |
* kernel text |
* kernel data |
* kernel text |
* kernel data |
*/ |
#include <arch/boot/boot.h> |
28,9 → 28,9 |
ktext_end = .; |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
hardcoded_load_address = .; |
LONG(PA2KA(BOOT_OFFSET)); |
hardcoded_ktext_size = .; |
42,23 → 42,23 |
hardcoded_unmapped_kdata_size = .; |
LONG(unmapped_kdata_end - unmapped_kdata_start); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
kdata_end = .; |
} |
/DISCARD/ : { |
*(.note.GNU-stack); |
*(.note.GNU-stack); |
*(.comment); |
} |
#ifdef CONFIG_SMP |
#ifdef CONFIG_SMP |
_hardcoded_unmapped_size = (unmapped_ktext_end - unmapped_ktext_start) + (unmapped_kdata_end - unmapped_kdata_start); |
ap_boot = unmapped_ap_boot - BOOT_OFFSET + AP_BOOT_OFFSET; |
ap_gdtr = unmapped_ap_gdtr - BOOT_OFFSET + AP_BOOT_OFFSET; |
protected_ap_gdtr = PA2KA(ap_gdtr); |
#endif /* CONFIG_SMP */ |
} |
/branches/dd/kernel/arch/ia32xen/include/context_offset.h |
---|
0,0 → 1,0 |
link ../../ia32/include/context_offset.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/mm/frame.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_FRAME_H_ |
#define KERN_ia32xen_FRAME_H_ |
#define FRAME_WIDTH 12 /* 4K */ |
#define FRAME_SIZE (1 << FRAME_WIDTH) |
#ifdef KERNEL |
#ifndef __ASM__ |
#define PA2MA(x) ((start_info.pm_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
#define MA2PA(x) ((mp_map[((uintptr_t) (x)) >> 12] << 12) + (((uintptr_t) (x)) & 0xfff)) |
extern void frame_arch_init(void); |
extern void physmem_print(void); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/mm/page.h |
---|
0,0 → 1,259 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PAGE_H_ |
#define KERN_ia32xen_PAGE_H_ |
#include <arch/mm/frame.h> |
#define PAGE_WIDTH FRAME_WIDTH |
#define PAGE_SIZE FRAME_SIZE |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#ifdef KERNEL |
#ifndef __ASM__ |
# define KA2PA(x) (((uintptr_t) (x)) - 0x80000000) |
# define PA2KA(x) (((uintptr_t) (x)) + 0x80000000) |
#else |
# define KA2PA(x) ((x) - 0x80000000) |
# define PA2KA(x) ((x) + 0x80000000) |
#endif |
/* |
* Implementation of generic 4-level page table interface. |
* IA-32 has 2-level page tables, so PTL1 and PTL2 are left out. |
*/ |
/* Number of entries in each level. */ |
#define PTL0_ENTRIES_ARCH 1024 |
#define PTL1_ENTRIES_ARCH 0 |
#define PTL2_ENTRIES_ARCH 0 |
#define PTL3_ENTRIES_ARCH 1024 |
/* Page table size for each level. */ |
#define PTL0_SIZE_ARCH ONE_FRAME |
#define PTL1_SIZE_ARCH 0 |
#define PTL2_SIZE_ARCH 0 |
#define PTL3_SIZE_ARCH ONE_FRAME |
/* Macros calculating indices into page tables in each level. */ |
#define PTL0_INDEX_ARCH(vaddr) (((vaddr) >> 22) & 0x3ff) |
#define PTL1_INDEX_ARCH(vaddr) 0 |
#define PTL2_INDEX_ARCH(vaddr) 0 |
#define PTL3_INDEX_ARCH(vaddr) (((vaddr) >> 12) & 0x3ff) |
/* Get PTE address accessors for each level. */ |
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \ |
((pte_t *) MA2PA((((pte_t *) (ptl0))[(i)].frame_address) << 12)) |
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \ |
(ptl1) |
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \ |
(ptl2) |
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \ |
((uintptr_t) MA2PA((((pte_t *) (ptl3))[(i)].frame_address) << 12)) |
/* Set PTE address accessors for each level. */ |
#define SET_PTL0_ADDRESS_ARCH(ptl0) \ |
{ \ |
mmuext_op_t mmu_ext; \ |
\ |
mmu_ext.cmd = MMUEXT_NEW_BASEPTR; \ |
mmu_ext.mfn = ADDR2PFN(PA2MA(ptl0)); \ |
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \ |
} |
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \ |
{ \ |
mmuext_op_t mmu_ext; \ |
\ |
mmu_ext.cmd = MMUEXT_PIN_L1_TABLE; \ |
mmu_ext.mfn = ADDR2PFN(PA2MA(a)); \ |
ASSERT(xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF) == 0); \ |
\ |
mmu_update_t update; \ |
\ |
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl0))[(i)])); \ |
update.val = PA2MA(a); \ |
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \ |
} |
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a) |
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a) |
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \ |
{ \ |
mmu_update_t update; \ |
\ |
update.ptr = PA2MA(KA2PA(&((pte_t *) (ptl3))[(i)])); \ |
update.val = PA2MA(a); \ |
ASSERT(xen_mmu_update(&update, 1, NULL, DOMID_SELF) == 0); \ |
} |
/* Get PTE flags accessors for each level. */ |
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \ |
get_pt_flags((pte_t *) (ptl0), (index_t) (i)) |
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \ |
PAGE_PRESENT |
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \ |
PAGE_PRESENT |
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \ |
get_pt_flags((pte_t *) (ptl3), (index_t) (i)) |
/* Set PTE flags accessors for each level. */ |
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \ |
set_pt_flags((pte_t *) (ptl0), (index_t) (i), (x)) |
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x) |
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x) |
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \ |
set_pt_flags((pte_t *) (ptl3), (index_t) (i), (x)) |
/* Query macros for the last level. */ |
#define PTE_VALID_ARCH(p) \ |
(*((uint32_t *) (p)) != 0) |
#define PTE_PRESENT_ARCH(p) \ |
((p)->present != 0) |
#define PTE_GET_FRAME_ARCH(p) \ |
((p)->frame_address << FRAME_WIDTH) |
#define PTE_WRITABLE_ARCH(p) \ |
((p)->writeable != 0) |
#define PTE_EXECUTABLE_ARCH(p) \ |
1 |
#ifndef __ASM__ |
#include <mm/mm.h> |
#include <arch/hypercall.h> |
#include <arch/interrupt.h> |
/* Page fault error codes. */ |
/** When bit on this position is 0, the page fault was caused by a not-present |
* page. |
*/ |
#define PFERR_CODE_P (1 << 0) |
/** When bit on this position is 1, the page fault was caused by a write. */ |
#define PFERR_CODE_RW (1 << 1) |
/** When bit on this position is 1, the page fault was caused in user mode. */ |
#define PFERR_CODE_US (1 << 2) |
/** When bit on this position is 1, a reserved bit was set in page directory. */ |
#define PFERR_CODE_RSVD (1 << 3) |
typedef struct { |
uint64_t ptr; /**< Machine address of PTE */ |
union { /**< New contents of PTE */ |
uint64_t val; |
pte_t pte; |
}; |
} mmu_update_t; |
typedef struct { |
unsigned int cmd; |
union { |
unsigned long mfn; |
unsigned long linear_addr; |
}; |
union { |
unsigned int nr_ents; |
void *vcpumask; |
}; |
} mmuext_op_t; |
static inline int xen_update_va_mapping(const void *va, const pte_t pte, |
const unsigned int flags) |
{ |
return hypercall4(XEN_UPDATE_VA_MAPPING, va, pte, 0, flags); |
} |
static inline int xen_mmu_update(const mmu_update_t *req, |
const unsigned int count, unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMU_UPDATE, req, count, success_count, domid); |
} |
static inline int xen_mmuext_op(const mmuext_op_t *op, const unsigned int count, |
unsigned int *success_count, domid_t domid) |
{ |
return hypercall4(XEN_MMUEXT_OP, op, count, success_count, domid); |
} |
static inline int get_pt_flags(pte_t *pt, index_t i) |
{ |
pte_t *p = &pt[i]; |
return ((!p->page_cache_disable) << PAGE_CACHEABLE_SHIFT | |
(!p->present) << PAGE_PRESENT_SHIFT | |
p->uaccessible << PAGE_USER_SHIFT | |
1 << PAGE_READ_SHIFT | |
p->writeable << PAGE_WRITE_SHIFT | |
1 << PAGE_EXEC_SHIFT | |
p->global << PAGE_GLOBAL_SHIFT); |
} |
static inline void set_pt_flags(pte_t *pt, index_t i, int flags) |
{ |
pte_t p = pt[i]; |
p.page_cache_disable = !(flags & PAGE_CACHEABLE); |
p.present = !(flags & PAGE_NOT_PRESENT); |
p.uaccessible = (flags & PAGE_USER) != 0; |
p.writeable = (flags & PAGE_WRITE) != 0; |
p.global = (flags & PAGE_GLOBAL) != 0; |
/* |
* Ensure that there is at least one bit set even if the present bit is cleared. |
*/ |
p.soft_valid = true; |
mmu_update_t update; |
update.ptr = PA2MA(KA2PA(&(pt[i]))); |
update.pte = p; |
xen_mmu_update(&update, 1, NULL, DOMID_SELF); |
} |
extern void page_arch_init(void); |
extern void page_fault(int n, istate_t *istate); |
#endif /* __ASM__ */ |
#endif /* KERNEL */ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/mm/as.h |
---|
0,0 → 1,64 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_AS_H_ |
#define KERN_ia32xen_AS_H_ |
#define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 |
#define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x80000000) |
#define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffff) |
#define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x00000000) |
#define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0x7fffffff) |
#define USTACK_ADDRESS_ARCH (USER_ADDRESS_SPACE_END_ARCH-(PAGE_SIZE-1)) |
typedef struct { |
} as_arch_t; |
#include <genarch/mm/as_pt.h> |
#define as_constructor_arch(as, flags) (as != as) |
#define as_destructor_arch(as) (as != as) |
#define as_create_arch(as, flags) (as != as) |
#define as_install_arch(as) |
#define as_deinstall_arch(as) |
#define as_invalidate_translation_cache(as, page, cnt) |
extern void as_arch_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/mm/asid.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
/* |
* ia32xen has no hardware support for address space identifiers. |
* This file is provided to do nop-implementation of mm/asid.h |
* interface. |
*/ |
#ifndef KERN_ia32xen_ASID_H_ |
#define KERN_ia32xen_ASID_H_ |
typedef int asid_t; |
#define ASID_MAX_ARCH 3 |
#define asid_get() (ASID_START+1) |
#define asid_put(asid) |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/mm/tlb.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TLB_H_ |
#define KERN_ia32xen_TLB_H_ |
#define tlb_arch_init() |
#define tlb_print() |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/types.h |
---|
0,0 → 1,91 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_TYPES_H_ |
#define KERN_ia32xen_TYPES_H_ |
#define NULL 0 |
#define false 0 |
#define true 1 |
typedef signed char int8_t; |
typedef signed short int16_t; |
typedef signed long int32_t; |
typedef signed long long int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned long uint32_t; |
typedef unsigned long long uint64_t; |
typedef uint32_t size_t; |
typedef uint32_t count_t; |
typedef uint32_t index_t; |
typedef uint32_t uintptr_t; |
typedef uint32_t pfn_t; |
typedef uint8_t ipl_t; |
typedef uint32_t unative_t; |
typedef int32_t native_t; |
typedef uint8_t bool; |
typedef uint64_t thread_id_t; |
typedef uint64_t task_id_t; |
typedef uint32_t context_id_t; |
typedef int32_t inr_t; |
typedef int32_t devno_t; |
/** Page Table Entry. */ |
typedef struct { |
unsigned present : 1; |
unsigned writeable : 1; |
unsigned uaccessible : 1; |
unsigned page_write_through : 1; |
unsigned page_cache_disable : 1; |
unsigned accessed : 1; |
unsigned dirty : 1; |
unsigned pat : 1; |
unsigned global : 1; |
unsigned soft_valid : 1; /**< Valid content even if the present bit is not set. */ |
unsigned avl : 2; |
unsigned frame_address : 20; |
} __attribute__ ((packed)) pte_t; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/pm.h |
---|
0,0 → 1,159 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_PM_H_ |
#define KERN_ia32xen_PM_H_ |
#define IDT_ITEMS 64 |
#define GDT_ITEMS 7 |
#define NULL_DES 0 |
#define KTEXT_DES 1 |
#define KDATA_DES 2 |
#define UTEXT_DES 3 |
#define UDATA_DES 4 |
#define TSS_DES 5 |
#define TLS_DES 6 /* Pointer to Thread-Local-Storage data */ |
#define selector(des) ((des) << 3) |
#define PL_KERNEL 1 |
#define PL_USER 3 |
#define AR_PRESENT (1<<7) |
#define AR_DATA (2<<3) |
#define AR_CODE (3<<3) |
#define AR_WRITABLE (1<<1) |
#define AR_INTERRUPT (0xe) |
#define AR_TSS (0x9) |
#define DPL_KERNEL (PL_KERNEL<<5) |
#define DPL_USER (PL_USER<<5) |
#define TSS_BASIC_SIZE 104 |
#define TSS_IOMAP_SIZE (16*1024+1) /* 16K for bitmap + 1 terminating byte for convenience */ |
#define IO_PORTS (64*1024) |
#ifndef __ASM__ |
#include <arch/types.h> |
#include <arch/context.h> |
struct ptr_16_32 { |
uint16_t limit; |
uint32_t base; |
} __attribute__ ((packed)); |
typedef struct ptr_16_32 ptr_16_32_t; |
struct descriptor { |
unsigned limit_0_15: 16; |
unsigned base_0_15: 16; |
unsigned base_16_23: 8; |
unsigned access: 8; |
unsigned limit_16_19: 4; |
unsigned available: 1; |
unsigned unused: 1; |
unsigned special: 1; |
unsigned granularity : 1; |
unsigned base_24_31: 8; |
} __attribute__ ((packed)); |
typedef struct descriptor descriptor_t; |
struct tss { |
uint16_t link; |
unsigned : 16; |
uint32_t esp0; |
uint16_t ss0; |
unsigned : 16; |
uint32_t esp1; |
uint16_t ss1; |
unsigned : 16; |
uint32_t esp2; |
uint16_t ss2; |
unsigned : 16; |
uint32_t cr3; |
uint32_t eip; |
uint32_t eflags; |
uint32_t eax; |
uint32_t ecx; |
uint32_t edx; |
uint32_t ebx; |
uint32_t esp; |
uint32_t ebp; |
uint32_t esi; |
uint32_t edi; |
uint16_t es; |
unsigned : 16; |
uint16_t cs; |
unsigned : 16; |
uint16_t ss; |
unsigned : 16; |
uint16_t ds; |
unsigned : 16; |
uint16_t fs; |
unsigned : 16; |
uint16_t gs; |
unsigned : 16; |
uint16_t ldtr; |
unsigned : 16; |
unsigned : 16; |
uint16_t iomap_base; |
uint8_t iomap[TSS_IOMAP_SIZE]; |
} __attribute__ ((packed)); |
typedef struct tss tss_t; |
extern ptr_16_32_t gdtr; |
extern ptr_16_32_t bootstrap_gdtr; |
extern ptr_16_32_t protected_ap_gdtr; |
extern struct tss *tss_p; |
extern descriptor_t gdt[]; |
extern void pm_init(void); |
extern void gdt_setbase(descriptor_t *d, uintptr_t base); |
extern void gdt_setlimit(descriptor_t *d, uint32_t limit); |
extern void traps_init(void); |
extern void tss_initialize(tss_t *t); |
extern void set_tls_desc(uintptr_t tls); |
#endif /* __ASM__ */ |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/hypercall.h |
---|
0,0 → 1,381 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef KERN_ia32xen_HYPERCALL_H_ |
#define KERN_ia32xen_HYPERCALL_H_ |
#ifndef __ASM__ |
# include <arch/types.h> |
# include <macros.h> |
#endif |
#define GUEST_CMDLINE 1024 |
#define VIRT_CPUS 32 |
#define START_INFO_SIZE 1104 |
#define BOOT_OFFSET 0x0000 |
#define TEMP_STACK_SIZE 0x1000 |
#define XEN_VIRT_START 0xFC000000 |
#define XEN_CS 0xe019 |
#define XEN_ELFNOTE_INFO 0 |
#define XEN_ELFNOTE_ENTRY 1 |
#define XEN_ELFNOTE_HYPERCALL_PAGE 2 |
#define XEN_ELFNOTE_VIRT_BASE 3 |
#define XEN_ELFNOTE_PADDR_OFFSET 4 |
#define XEN_ELFNOTE_XEN_VERSION 5 |
#define XEN_ELFNOTE_GUEST_OS 6 |
#define XEN_ELFNOTE_GUEST_VERSION 7 |
#define XEN_ELFNOTE_LOADER 8 |
#define XEN_ELFNOTE_PAE_MODE 9 |
#define XEN_ELFNOTE_FEATURES 10 |
#define XEN_ELFNOTE_BSD_SYMTAB 11 |
#define mp_map ((pfn_t *) XEN_VIRT_START) |
#define SIF_PRIVILEGED (1 << 0) /**< Privileged domain */ |
#define SIF_INITDOMAIN (1 << 1) /**< Iinitial control domain */ |
#define XEN_CONSOLE_VGA 0x03 |
#define XEN_CONSOLE_VESA 0x23 |
#define XEN_SET_TRAP_TABLE 0 |
#define XEN_MMU_UPDATE 1 |
#define XEN_SET_CALLBACKS 4 |
#define XEN_UPDATE_VA_MAPPING 14 |
#define XEN_EVENT_CHANNEL_OP 16 |
#define XEN_VERSION 17 |
#define XEN_CONSOLE_IO 18 |
#define XEN_MMUEXT_OP 26 |
/* |
* Commands for XEN_CONSOLE_IO |
*/ |
#define CONSOLE_IO_WRITE 0 |
#define CONSOLE_IO_READ 1 |
#define MMUEXT_PIN_L1_TABLE 0 |
#define MMUEXT_PIN_L2_TABLE 1 |
#define MMUEXT_PIN_L3_TABLE 2 |
#define MMUEXT_PIN_L4_TABLE 3 |
#define MMUEXT_UNPIN_TABLE 4 |
#define MMUEXT_NEW_BASEPTR 5 |
#define MMUEXT_TLB_FLUSH_LOCAL 6 |
#define MMUEXT_INVLPG_LOCAL 7 |
#define MMUEXT_TLB_FLUSH_MULTI 8 |
#define MMUEXT_INVLPG_MULTI 9 |
#define MMUEXT_TLB_FLUSH_ALL 10 |
#define MMUEXT_INVLPG_ALL 11 |
#define MMUEXT_FLUSH_CACHE 12 |
#define MMUEXT_SET_LDT 13 |
#define MMUEXT_NEW_USER_BASEPTR 15 |
#define EVTCHNOP_SEND 4 |
#define UVMF_NONE 0 /**< No flushing at all */ |
#define UVMF_TLB_FLUSH 1 /**< Flush entire TLB(s) */ |
#define UVMF_INVLPG 2 /**< Flush only one entry */ |
#define UVMF_FLUSHTYPE_MASK 3 |
#define UVMF_MULTI 0 /**< Flush subset of TLBs */ |
#define UVMF_LOCAL 0 /**< Flush local TLB */ |
#define UVMF_ALL (1 << 2) /**< Flush all TLBs */ |
#define DOMID_SELF (0x7FF0U) |
#define DOMID_IO (0x7FF1U) |
#ifndef __ASM__ |
typedef uint16_t domid_t; |
typedef uint32_t evtchn_t; |
typedef struct { |
uint32_t version; |
uint32_t pad0; |
uint64_t tsc_timestamp; /**< TSC at last update of time vals */ |
uint64_t system_time; /**< Time, in nanosecs, since boot */ |
uint32_t tsc_to_system_mul; |
int8_t tsc_shift; |
int8_t pad1[3]; |
} vcpu_time_info_t; |
typedef struct { |
uint32_t cr2; |
uint32_t pad[5]; |
} arch_vcpu_info_t; |
typedef struct arch_shared_info { |
pfn_t max_pfn; /**< max pfn that appears in table */ |
uint32_t pfn_to_mfn_frame_list_list; |
uint32_t nmi_reason; |
} arch_shared_info_t; |
typedef struct { |
uint8_t evtchn_upcall_pending; |
ipl_t evtchn_upcall_mask; |
evtchn_t evtchn_pending_sel; |
arch_vcpu_info_t arch; |
vcpu_time_info_t time; |
} vcpu_info_t; |
typedef struct { |
vcpu_info_t vcpu_info[VIRT_CPUS]; |
evtchn_t evtchn_pending[32]; |
evtchn_t evtchn_mask[32]; |
uint32_t wc_version; /**< Version counter */ |
uint32_t wc_sec; /**< Secs 00:00:00 UTC, Jan 1, 1970 */ |
uint32_t wc_nsec; /**< Nsecs 00:00:00 UTC, Jan 1, 1970 */ |
arch_shared_info_t arch; |
} shared_info_t; |
typedef struct { |
int8_t magic[32]; /**< "xen-<version>-<platform>" */ |
uint32_t frames; /**< Available frames */ |
shared_info_t *shared_info; /**< Shared info structure (machine address) */ |
uint32_t flags; /**< SIF_xxx flags */ |
pfn_t store_mfn; /**< Shared page (machine page) */ |
evtchn_t store_evtchn; /**< Event channel for store communication */ |
union { |
struct { |
pfn_t mfn; /**< Console page (machine page) */ |
evtchn_t evtchn; /**< Event channel for console messages */ |
} domU; |
struct { |
uint32_t info_off; /**< Offset of console_info struct */ |
uint32_t info_size; /**< Size of console_info struct from start */ |
} dom0; |
} console; |
pte_t *ptl0; /**< Boot PTL0 (kernel address) */ |
uint32_t pt_frames; /**< Number of bootstrap page table frames */ |
pfn_t *pm_map; /**< Physical->machine frame map (kernel address) */ |
void *mod_start; /**< Modules start (kernel address) */ |
uint32_t mod_len; /**< Modules size (bytes) */ |
int8_t cmd_line[GUEST_CMDLINE]; |
} start_info_t; |
typedef struct { |
uint8_t video_type; |
union { |
struct { |
uint16_t font_height; |
uint16_t cursor_x; |
uint16_t cursor_y; |
uint16_t rows; |
uint16_t columns; |
} vga; |
struct { |
uint16_t width; |
uint16_t height; |
uint16_t bytes_per_line; |
uint16_t bits_per_pixel; |
uint32_t lfb_base; |
uint32_t lfb_size; |
uint8_t red_pos; |
uint8_t red_size; |
uint8_t green_pos; |
uint8_t green_size; |
uint8_t blue_pos; |
uint8_t blue_size; |
uint8_t rsvd_pos; |
uint8_t rsvd_size; |
} vesa_lfb; |
} info; |
} console_info_t; |
typedef struct { |
pfn_t start; |
pfn_t size; |
pfn_t reserved; |
} memzone_t; |
extern start_info_t start_info; |
extern shared_info_t shared_info; |
extern memzone_t meminfo; |
typedef struct { |
uint8_t vector; /**< Exception vector */ |
uint8_t flags; /**< 0-3: privilege level; 4: clear event enable */ |
uint16_t cs; /**< Code selector */ |
void *address; /**< Code offset */ |
} trap_info_t; |
typedef struct { |
evtchn_t port; |
} evtchn_send_t; |
typedef struct { |
uint32_t cmd; |
union { |
evtchn_send_t send; |
}; |
} evtchn_op_t; |
#define force_evtchn_callback() ((void) xen_version(0, 0)) |
#define hypercall0(id) \ |
({ \ |
unative_t ret; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret) \ |
: \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall1(id, p1) \ |
({ \ |
unative_t ret, __ign1; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1) \ |
: "1" (p1) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall2(id, p1, p2) \ |
({ \ |
unative_t ret, __ign1, __ign2; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2) \ |
: "1" (p1), \ |
"2" (p2) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall3(id, p1, p2, p3) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall4(id, p1, p2, p3, p4) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
#define hypercall5(id, p1, p2, p3, p4, p5) \ |
({ \ |
unative_t ret, __ign1, __ign2, __ign3, __ign4, __ign5; \ |
asm volatile ( \ |
"call hypercall_page + (" STRING(id) " * 32)\n" \ |
: "=a" (ret), \ |
"=b" (__ign1), \ |
"=c" (__ign2), \ |
"=d" (__ign3), \ |
"=S" (__ign4), \ |
"=D" (__ign5) \ |
: "1" (p1), \ |
"2" (p2), \ |
"3" (p3), \ |
"4" (p4), \ |
"5" (p5) \ |
: "memory" \ |
); \ |
ret; \ |
}) |
static inline int xen_console_io(const unsigned int cmd, const unsigned int count, const char *str) |
{ |
return hypercall3(XEN_CONSOLE_IO, cmd, count, str); |
} |
static inline int xen_set_callbacks(const unsigned int event_selector, const void *event_address, const unsigned int failsafe_selector, void *failsafe_address) |
{ |
return hypercall4(XEN_SET_CALLBACKS, event_selector, event_address, failsafe_selector, failsafe_address); |
} |
static inline int xen_set_trap_table(const trap_info_t *table) |
{ |
return hypercall1(XEN_SET_TRAP_TABLE, table); |
} |
static inline int xen_version(const unsigned int cmd, const void *arg) |
{ |
return hypercall2(XEN_VERSION, cmd, arg); |
} |
static inline int xen_notify_remote(evtchn_t channel) |
{ |
evtchn_op_t op; |
op.cmd = EVTCHNOP_SEND; |
op.send.port = channel; |
return hypercall1(XEN_EVENT_CHANNEL_OP, &op); |
} |
#endif |
#endif |
/branches/dd/kernel/arch/ia32xen/include/asm.h |
---|
0,0 → 1,272 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2005 Sergey Bondari |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_ASM_H_ |
#define KERN_ia32xen_ASM_H_ |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch/barrier.h> |
#include <config.h> |
extern void enable_l_apic_in_msr(void); |
extern void asm_delay_loop(uint32_t t); |
extern void asm_fake_loop(uint32_t t); |
/** Halt CPU |
* |
* Halt the current CPU until interrupt event. |
*/ |
#define cpu_halt() ((void) 0) |
#define cpu_sleep() ((void) 0) |
#define GEN_READ_REG(reg) static inline unative_t read_ ##reg (void) \ |
{ \ |
unative_t res; \ |
asm volatile ("movl %%" #reg ", %0" : "=r" (res) ); \ |
return res; \ |
} |
#define GEN_WRITE_REG(reg) static inline void write_ ##reg (unative_t regn) \ |
{ \ |
asm volatile ("movl %0, %%" #reg : : "r" (regn)); \ |
} |
GEN_READ_REG(cr0); |
GEN_READ_REG(cr2); |
GEN_READ_REG(dr0); |
GEN_READ_REG(dr1); |
GEN_READ_REG(dr2); |
GEN_READ_REG(dr3); |
GEN_READ_REG(dr6); |
GEN_READ_REG(dr7); |
GEN_WRITE_REG(dr0); |
GEN_WRITE_REG(dr1); |
GEN_WRITE_REG(dr2); |
GEN_WRITE_REG(dr3); |
GEN_WRITE_REG(dr6); |
GEN_WRITE_REG(dr7); |
/** Byte to port |
* |
* Output byte to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outb(uint16_t port, uint8_t val) { asm volatile ("outb %b0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Word to port |
* |
* Output word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outw(uint16_t port, uint16_t val) { asm volatile ("outw %w0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Double word to port |
* |
* Output double word to port |
* |
* @param port Port to write to |
* @param val Value to write |
*/ |
static inline void outl(uint16_t port, uint32_t val) { asm volatile ("outl %l0, %w1\n" : : "a" (val), "d" (port) ); } |
/** Byte from port |
* |
* Get byte from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint8_t inb(uint16_t port) { uint8_t val; asm volatile ("inb %w1, %b0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Word from port |
* |
* Get word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint16_t inw(uint16_t port) { uint16_t val; asm volatile ("inw %w1, %w0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Double word from port |
* |
* Get double word from port |
* |
* @param port Port to read from |
* @return Value read |
*/ |
static inline uint32_t inl(uint16_t port) { uint32_t val; asm volatile ("inl %w1, %l0 \n" : "=a" (val) : "d" (port) ); return val; } |
/** Enable interrupts. |
* |
* Enable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_enable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
write_barrier(); |
shared_info.vcpu_info[0].evtchn_upcall_mask = 0; |
write_barrier(); |
if (shared_info.vcpu_info[0].evtchn_upcall_pending) |
force_evtchn_callback(); |
return v; |
} |
/** Disable interrupts. |
* |
* Disable interrupts and return previous |
* value of EFLAGS. |
* |
* @return Old interrupt priority level. |
*/ |
static inline ipl_t interrupts_disable(void) |
{ |
// FIXME SMP |
ipl_t v = shared_info.vcpu_info[0].evtchn_upcall_mask; |
shared_info.vcpu_info[0].evtchn_upcall_mask = 1; |
write_barrier(); |
return v; |
} |
/** Restore interrupt priority level. |
* |
* Restore EFLAGS. |
* |
* @param ipl Saved interrupt priority level. |
*/ |
static inline void interrupts_restore(ipl_t ipl) |
{ |
if (ipl == 0) |
interrupts_enable(); |
else |
interrupts_disable(); |
} |
/** Return interrupt priority level. |
* |
* @return EFLAFS. |
*/ |
static inline ipl_t interrupts_read(void) |
{ |
// FIXME SMP |
return shared_info.vcpu_info[0].evtchn_upcall_mask; |
} |
/** Return base address of current stack |
* |
* Return the base address of the current stack. |
* The stack is assumed to be STACK_SIZE bytes long. |
* The stack must start on page boundary. |
*/ |
static inline uintptr_t get_stack_base(void) |
{ |
uintptr_t v; |
asm volatile ("andl %%esp, %0\n" : "=r" (v) : "0" (~(STACK_SIZE-1))); |
return v; |
} |
/** Return current IP address */ |
static inline uintptr_t * get_ip() |
{ |
uintptr_t *ip; |
asm volatile ( |
"mov %%eip, %0" |
: "=r" (ip) |
); |
return ip; |
} |
/** Invalidate TLB Entry. |
* |
* @param addr Address on a page whose TLB entry is to be invalidated. |
*/ |
static inline void invlpg(uintptr_t addr) |
{ |
asm volatile ("invlpg %0\n" :: "m" (*(unative_t *)addr)); |
} |
/** Load GDTR register from memory. |
* |
* @param gdtr_reg Address of memory from where to load GDTR. |
*/ |
static inline void gdtr_load(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("lgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Store GDTR register to memory. |
* |
* @param gdtr_reg Address of memory to where to load GDTR. |
*/ |
static inline void gdtr_store(ptr_16_32_t *gdtr_reg) |
{ |
asm volatile ("sgdtl %0\n" : : "m" (*gdtr_reg)); |
} |
/** Load TR from descriptor table. |
* |
* @param sel Selector specifying descriptor of TSS segment. |
*/ |
static inline void tr_load(uint16_t sel) |
{ |
asm volatile ("ltr %0" : : "r" (sel)); |
} |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/drivers/xconsole.h |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_ia32xen_XCONSOLE_H_ |
#define KERN_ia32xen_XCONSOLE_H_ |
#include <arch/types.h> |
typedef struct { |
char in[1024]; |
char out[2048]; |
uint32_t in_cons; |
uint32_t in_prod; |
uint32_t out_cons; |
uint32_t out_prod; |
} xencons_t; |
extern xencons_t console_page; |
extern void xen_console_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/include/cycle.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cycle.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/interrupt.h |
---|
0,0 → 1,0 |
link ../../ia32/include/interrupt.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/fpu_context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/fpu_context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/byteorder.h |
---|
0,0 → 1,0 |
link ../../ia32/include/byteorder.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/cpuid.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpuid.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/elf.h |
---|
0,0 → 1,0 |
link ../../ia32/include/elf.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/bios |
---|
0,0 → 1,0 |
link ../../ia32/include/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/memstr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/memstr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/arg.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arg.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/smp |
---|
0,0 → 1,0 |
link ../../ia32/include/smp |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/ddi |
---|
0,0 → 1,0 |
link ../../ia32/include/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/atomic.h |
---|
0,0 → 1,0 |
link ../../ia32/include/atomic.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/arch.h |
---|
0,0 → 1,0 |
link ../../ia32/include/arch.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/proc |
---|
0,0 → 1,0 |
link ../../ia32/include/proc |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/faddr.h |
---|
0,0 → 1,0 |
link ../../ia32/include/faddr.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/debugger.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debugger.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/context.h |
---|
0,0 → 1,0 |
link ../../ia32/include/context.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/debug.h |
---|
0,0 → 1,0 |
link ../../ia32/include/debug.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/barrier.h |
---|
0,0 → 1,0 |
link ../../ia32/include/barrier.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/include/cpu.h |
---|
0,0 → 1,0 |
link ../../ia32/include/cpu.h |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/Makefile.inc |
---|
0,0 → 1,140 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
BFD_NAME = elf32-i386 |
BFD_ARCH = i386 |
BFD = elf32-i386 |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = /usr/local/i686 |
DEFS += -DMACHINE=$(MACHINE) -D__32_BITS__ |
CMN1 = -m32 |
GCC_CFLAGS += $(CMN1) |
ICC_CFLAGS += $(CMN1) |
SUNCC_CFLAGS += $(CMN1) |
## Accepted CPUs |
# |
ifeq ($(MACHINE),athlon-xp) |
CMN2 = -march=athlon-xp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_SMP = n |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),athlon-mp) |
CMN2 = -march=athlon-mp -mmmx -msse -m3dnow |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=ssea |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),pentium3) |
CMN2 = -march=pentium3 -mmmx -msse |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse |
DEFS += -DCONFIG_FENCES_P3 |
CONFIG_HT = n |
endif |
ifeq ($(MACHINE),core) |
CMN2 = -march=prescott -mfpmath=sse -mmmx -msse -msse2 -msse3 |
GCC_CFLAGS += $(CMN2) |
ICC_CFLAGS += $(CMN2) |
SUNCC_CFLAGS += -xarch=sse3 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
ifeq ($(MACHINE),pentium4) |
GCC_CFLAGS += -march=pentium4 -mfpmath=sse -mmmx -msse -msse2 |
ICC_CFLAGS += -march=pentium4 |
SUNCC_CFLAGS += -xarch=sse2 |
DEFS += -DCONFIG_FENCES_P4 |
endif |
## Own configuration directives |
# |
CONFIG_ACPI = y |
## Compile with hierarchical page tables support. |
# |
CONFIG_PAGE_PT = y |
DEFS += -DCONFIG_PAGE_PT |
## Accepted configuration directives |
# |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
ifeq ($(CONFIG_HT),y) |
DEFS += -DCONFIG_HT |
endif |
## Compile with support for software integer division. |
# |
CONFIG_SOFTINT = y |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/context.S \ |
arch/$(ARCH)/src/debug/panic.s \ |
arch/$(ARCH)/src/delay.s \ |
arch/$(ARCH)/src/asm.S \ |
arch/$(ARCH)/src/proc/scheduler.c \ |
arch/$(ARCH)/src/proc/task.c \ |
arch/$(ARCH)/src/proc/thread.c \ |
arch/$(ARCH)/src/bios/bios.c \ |
arch/$(ARCH)/src/smp/apic.c \ |
arch/$(ARCH)/src/smp/mps.c \ |
arch/$(ARCH)/src/smp/smp.c \ |
arch/$(ARCH)/src/atomic.S \ |
arch/$(ARCH)/src/smp/ipi.c \ |
arch/$(ARCH)/src/ia32xen.c \ |
arch/$(ARCH)/src/interrupt.c \ |
arch/$(ARCH)/src/pm.c \ |
arch/$(ARCH)/src/userspace.c \ |
arch/$(ARCH)/src/cpu/cpu.c \ |
arch/$(ARCH)/src/mm/as.c \ |
arch/$(ARCH)/src/mm/frame.c \ |
arch/$(ARCH)/src/mm/page.c \ |
arch/$(ARCH)/src/mm/tlb.c \ |
arch/$(ARCH)/src/ddi/ddi.c \ |
arch/$(ARCH)/src/drivers/xconsole.c \ |
arch/$(ARCH)/src/boot/boot.S \ |
arch/$(ARCH)/src/fpu_context.c \ |
arch/$(ARCH)/src/debugger.c |
/branches/dd/kernel/arch/ia32xen/src/context.S |
---|
0,0 → 1,0 |
link ../../ia32/src/context.S |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/smp/mps.c |
---|
0,0 → 1,433 |
/* |
* Copyright (c) 2001-2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <config.h> |
#include <print.h> |
#include <debug.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/smp.h> |
#include <func.h> |
#include <arch/types.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch/bios/bios.h> |
#include <mm/frame.h> |
/* |
* MultiProcessor Specification detection code. |
*/ |
#define FS_SIGNATURE 0x5f504d5f |
#define CT_SIGNATURE 0x504d4350 |
int mps_fs_check(uint8_t *base); |
int mps_ct_check(void); |
int configure_via_ct(void); |
int configure_via_default(uint8_t n); |
int ct_processor_entry(struct __processor_entry *pr); |
void ct_bus_entry(struct __bus_entry *bus); |
void ct_io_apic_entry(struct __io_apic_entry *ioa); |
void ct_io_intr_entry(struct __io_intr_entry *iointr); |
void ct_l_intr_entry(struct __l_intr_entry *lintr); |
void ct_extended_entries(void); |
static struct mps_fs *fs; |
static struct mps_ct *ct; |
struct __processor_entry *processor_entries = NULL; |
struct __bus_entry *bus_entries = NULL; |
struct __io_apic_entry *io_apic_entries = NULL; |
struct __io_intr_entry *io_intr_entries = NULL; |
struct __l_intr_entry *l_intr_entries = NULL; |
unsigned int processor_entry_cnt = 0; |
unsigned int bus_entry_cnt = 0; |
unsigned int io_apic_entry_cnt = 0; |
unsigned int io_intr_entry_cnt = 0; |
unsigned int l_intr_entry_cnt = 0; |
waitq_t ap_completion_wq; |
/* |
* Implementation of IA-32 SMP configuration interface. |
*/ |
static count_t get_cpu_count(void); |
static bool is_cpu_enabled(index_t i); |
static bool is_bsp(index_t i); |
static uint8_t get_cpu_apic_id(index_t i); |
static int mps_irq_to_pin(unsigned int irq); |
struct smp_config_operations mps_config_operations = { |
.cpu_count = get_cpu_count, |
.cpu_enabled = is_cpu_enabled, |
.cpu_bootstrap = is_bsp, |
.cpu_apic_id = get_cpu_apic_id, |
.irq_to_pin = mps_irq_to_pin |
}; |
count_t get_cpu_count(void) |
{ |
return processor_entry_cnt; |
} |
bool is_cpu_enabled(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x1; |
} |
bool is_bsp(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].cpu_flags & 0x2; |
} |
uint8_t get_cpu_apic_id(index_t i) |
{ |
ASSERT(i < processor_entry_cnt); |
return processor_entries[i].l_apic_id; |
} |
/* |
* Used to check the integrity of the MP Floating Structure. |
*/ |
int mps_fs_check(uint8_t *base) |
{ |
int i; |
uint8_t sum; |
for (i = 0, sum = 0; i < 16; i++) |
sum += base[i]; |
return !sum; |
} |
/* |
* Used to check the integrity of the MP Configuration Table. |
*/ |
int mps_ct_check(void) |
{ |
uint8_t *base = (uint8_t *) ct; |
uint8_t *ext = base + ct->base_table_length; |
uint8_t sum; |
int i; |
/* count the checksum for the base table */ |
for (i=0,sum=0; i < ct->base_table_length; i++) |
sum += base[i]; |
if (sum) |
return 0; |
/* count the checksum for the extended table */ |
for (i=0,sum=0; i < ct->ext_table_length; i++) |
sum += ext[i]; |
return sum == ct->ext_table_checksum; |
} |
void mps_init(void) |
{ |
uint8_t *addr[2] = { NULL, (uint8_t *) PA2KA(0xf0000) }; |
int i, j, length[2] = { 1024, 64*1024 }; |
/* |
* Find MP Floating Pointer Structure |
* 1a. search first 1K of EBDA |
* 1b. if EBDA is undefined, search last 1K of base memory |
* 2. search 64K starting at 0xf0000 |
*/ |
addr[0] = (uint8_t *) PA2KA(ebda ? ebda : 639 * 1024); |
for (i = 0; i < 2; i++) { |
for (j = 0; j < length[i]; j += 16) { |
if (*((uint32_t *) &addr[i][j]) == FS_SIGNATURE && mps_fs_check(&addr[i][j])) { |
fs = (struct mps_fs *) &addr[i][j]; |
goto fs_found; |
} |
} |
} |
return; |
fs_found: |
printf("%p: MPS Floating Pointer Structure\n", fs); |
if (fs->config_type == 0 && fs->configuration_table) { |
if (fs->mpfib2 >> 7) { |
printf("%s: PIC mode not supported\n", __func__); |
return; |
} |
ct = (struct mps_ct *)PA2KA((uintptr_t)fs->configuration_table); |
config.cpu_count = configure_via_ct(); |
} |
else |
config.cpu_count = configure_via_default(fs->config_type); |
return; |
} |
int configure_via_ct(void) |
{ |
uint8_t *cur; |
int i, cnt; |
if (ct->signature != CT_SIGNATURE) { |
printf("%s: bad ct->signature\n", __func__); |
return 1; |
} |
if (!mps_ct_check()) { |
printf("%s: bad ct checksum\n", __func__); |
return 1; |
} |
if (ct->oem_table) { |
printf("%s: ct->oem_table not supported\n", __func__); |
return 1; |
} |
l_apic = (uint32_t *)(uintptr_t)ct->l_apic; |
cnt = 0; |
cur = &ct->base_table[0]; |
for (i=0; i < ct->entry_count; i++) { |
switch (*cur) { |
/* Processor entry */ |
case 0: |
processor_entries = processor_entries ? processor_entries : (struct __processor_entry *) cur; |
processor_entry_cnt++; |
cnt += ct_processor_entry((struct __processor_entry *) cur); |
cur += 20; |
break; |
/* Bus entry */ |
case 1: |
bus_entries = bus_entries ? bus_entries : (struct __bus_entry *) cur; |
bus_entry_cnt++; |
ct_bus_entry((struct __bus_entry *) cur); |
cur += 8; |
break; |
/* I/O Apic */ |
case 2: |
io_apic_entries = io_apic_entries ? io_apic_entries : (struct __io_apic_entry *) cur; |
io_apic_entry_cnt++; |
ct_io_apic_entry((struct __io_apic_entry *) cur); |
cur += 8; |
break; |
/* I/O Interrupt Assignment */ |
case 3: |
io_intr_entries = io_intr_entries ? io_intr_entries : (struct __io_intr_entry *) cur; |
io_intr_entry_cnt++; |
ct_io_intr_entry((struct __io_intr_entry *) cur); |
cur += 8; |
break; |
/* Local Interrupt Assignment */ |
case 4: |
l_intr_entries = l_intr_entries ? l_intr_entries : (struct __l_intr_entry *) cur; |
l_intr_entry_cnt++; |
ct_l_intr_entry((struct __l_intr_entry *) cur); |
cur += 8; |
break; |
default: |
/* |
* Something is wrong. Fallback to UP mode. |
*/ |
printf("%s: ct badness\n", __func__); |
return 1; |
} |
} |
/* |
* Process extended entries. |
*/ |
ct_extended_entries(); |
return cnt; |
} |
int configure_via_default(uint8_t n) |
{ |
/* |
* Not yet implemented. |
*/ |
printf("%s: not supported\n", __func__); |
return 1; |
} |
int ct_processor_entry(struct __processor_entry *pr) |
{ |
/* |
* Ignore processors which are not marked enabled. |
*/ |
if ((pr->cpu_flags & (1<<0)) == 0) |
return 0; |
apic_id_mask |= (1<<pr->l_apic_id); |
return 1; |
} |
void ct_bus_entry(struct __bus_entry *bus) |
{ |
#ifdef MPSCT_VERBOSE |
char buf[7]; |
memcpy((void *) buf, (void *) bus->bus_type, 6); |
buf[6] = 0; |
printf("bus%d: %s\n", bus->bus_id, buf); |
#endif |
} |
void ct_io_apic_entry(struct __io_apic_entry *ioa) |
{ |
static int io_apic_count = 0; |
/* this ioapic is marked unusable */ |
if ((ioa->io_apic_flags & 1) == 0) |
return; |
if (io_apic_count++ > 0) { |
/* |
* Multiple IO APIC's are currently not supported. |
*/ |
return; |
} |
io_apic = (uint32_t *)(uintptr_t)ioa->io_apic; |
} |
//#define MPSCT_VERBOSE |
void ct_io_intr_entry(struct __io_intr_entry *iointr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (iointr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (iointr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((iointr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", iointr->src_bus_id, iointr->src_bus_irq); |
putchar(','); |
printf("io_apic%d,pin%d", iointr->dst_io_apic_id, iointr->dst_io_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_l_intr_entry(struct __l_intr_entry *lintr) |
{ |
#ifdef MPSCT_VERBOSE |
switch (lintr->intr_type) { |
case 0: printf("INT"); break; |
case 1: printf("NMI"); break; |
case 2: printf("SMI"); break; |
case 3: printf("ExtINT"); break; |
} |
putchar(','); |
switch (lintr->poel&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("active high"); break; |
case 2: printf("reserved"); break; |
case 3: printf("active low"); break; |
} |
putchar(','); |
switch ((lintr->poel>>2)&3) { |
case 0: printf("bus-like"); break; |
case 1: printf("edge-triggered"); break; |
case 2: printf("reserved"); break; |
case 3: printf("level-triggered"); break; |
} |
putchar(','); |
printf("bus%d,irq%d", lintr->src_bus_id, lintr->src_bus_irq); |
putchar(','); |
printf("l_apic%d,pin%d", lintr->dst_l_apic_id, lintr->dst_l_apic_pin); |
putchar('\n'); |
#endif |
} |
void ct_extended_entries(void) |
{ |
uint8_t *ext = (uint8_t *) ct + ct->base_table_length; |
uint8_t *cur; |
for (cur = ext; cur < ext + ct->ext_table_length; cur += cur[CT_EXT_ENTRY_LEN]) { |
switch (cur[CT_EXT_ENTRY_TYPE]) { |
default: |
printf("%p: skipping MP Configuration Table extended entry type %d\n", cur, cur[CT_EXT_ENTRY_TYPE]); |
break; |
} |
} |
} |
int mps_irq_to_pin(unsigned int irq) |
{ |
unsigned int i; |
for (i = 0; i < io_intr_entry_cnt; i++) { |
if (io_intr_entries[i].src_bus_irq == irq && io_intr_entries[i].intr_type == 0) |
return io_intr_entries[i].dst_io_apic_pin; |
} |
return -1; |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/smp/smp.c |
---|
0,0 → 1,174 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <smp/smp.h> |
#include <arch/smp/smp.h> |
#include <arch/smp/mps.h> |
#include <arch/smp/ap.h> |
#include <genarch/acpi/acpi.h> |
#include <genarch/acpi/madt.h> |
#include <config.h> |
#include <synch/waitq.h> |
#include <synch/synch.h> |
#include <arch/pm.h> |
#include <func.h> |
#include <panic.h> |
#include <debug.h> |
#include <arch/asm.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/slab.h> |
#include <mm/as.h> |
#include <print.h> |
#include <memstr.h> |
#ifdef CONFIG_SMP |
static struct smp_config_operations *ops = NULL; |
void smp_init(void) |
{ |
uintptr_t l_apic_address, io_apic_address; |
if (acpi_madt) { |
acpi_madt_parse(); |
ops = &madt_config_operations; |
} |
if (config.cpu_count == 1) { |
mps_init(); |
ops = &mps_config_operations; |
} |
l_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!l_apic_address) |
panic("cannot allocate address for l_apic\n"); |
io_apic_address = (uintptr_t) frame_alloc(ONE_FRAME, FRAME_ATOMIC | FRAME_KA); |
if (!io_apic_address) |
panic("cannot allocate address for io_apic\n"); |
if (config.cpu_count > 1) { |
page_mapping_insert(AS_KERNEL, l_apic_address, (uintptr_t) l_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
page_mapping_insert(AS_KERNEL, io_apic_address, (uintptr_t) io_apic, |
PAGE_NOT_CACHEABLE | PAGE_WRITE); |
l_apic = (uint32_t *) l_apic_address; |
io_apic = (uint32_t *) io_apic_address; |
} |
} |
/* |
* Kernel thread for bringing up application processors. It becomes clear |
* that we need an arrangement like this (AP's being initialized by a kernel |
* thread), for a thread has its dedicated stack. (The stack used during the |
* BSP initialization (prior the very first call to scheduler()) will be used |
* as an initialization stack for each AP.) |
*/ |
void kmp(void *arg) |
{ |
unsigned int i; |
ASSERT(ops != NULL); |
waitq_initialize(&ap_completion_wq); |
/* |
* We need to access data in frame 0. |
* We boldly make use of kernel address space mapping. |
*/ |
/* |
* Save 0xa to address 0xf of the CMOS RAM. |
* BIOS will not do the POST after the INIT signal. |
*/ |
outb(0x70,0xf); |
outb(0x71,0xa); |
// pic_disable_irqs(0xffff); |
apic_init(); |
for (i = 0; i < ops->cpu_count(); i++) { |
struct descriptor *gdt_new; |
/* |
* Skip processors marked unusable. |
*/ |
if (!ops->cpu_enabled(i)) |
continue; |
/* |
* The bootstrap processor is already up. |
*/ |
if (ops->cpu_bootstrap(i)) |
continue; |
if (ops->cpu_apic_id(i) == l_apic_id()) { |
printf("%s: bad processor entry #%d, will not send IPI to myself\n", __FUNCTION__, i); |
continue; |
} |
/* |
* Prepare new GDT for CPU in question. |
*/ |
if (!(gdt_new = (struct descriptor *) malloc(GDT_ITEMS*sizeof(struct descriptor), FRAME_ATOMIC))) |
panic("couldn't allocate memory for GDT\n"); |
memcpy(gdt_new, gdt, GDT_ITEMS * sizeof(struct descriptor)); |
memsetb((uintptr_t)(&gdt_new[TSS_DES]), sizeof(struct descriptor), 0); |
gdtr.base = (uintptr_t) gdt_new; |
if (l_apic_send_init_ipi(ops->cpu_apic_id(i))) { |
/* |
* There may be just one AP being initialized at |
* the time. After it comes completely up, it is |
* supposed to wake us up. |
*/ |
if (waitq_sleep_timeout(&ap_completion_wq, 1000000, SYNCH_FLAGS_NONE) == ESYNCH_TIMEOUT) |
printf("%s: waiting for cpu%d (APIC ID = %d) timed out\n", __FUNCTION__, config.cpu_active > i ? config.cpu_active : i, ops->cpu_apic_id(i)); |
} else |
printf("INIT IPI for l_apic%d failed\n", ops->cpu_apic_id(i)); |
} |
} |
int smp_irq_to_pin(unsigned int irq) |
{ |
ASSERT(ops != NULL); |
return ops->irq_to_pin(irq); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/smp/apic.c |
---|
0,0 → 1,581 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/types.h> |
#include <arch/smp/apic.h> |
#include <arch/smp/ap.h> |
#include <arch/smp/mps.h> |
#include <mm/page.h> |
#include <time/delay.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <print.h> |
#include <arch/asm.h> |
#include <arch.h> |
#ifdef CONFIG_SMP |
/* |
* Advanced Programmable Interrupt Controller for SMP systems. |
* Tested on: |
* Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs |
* Simics 2.0.28 - Simics 2.2.19 2-15 CPUs |
* VMware Workstation 5.5 with 2 CPUs |
* QEMU 0.8.0 with 2-15 CPUs |
* ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs |
* ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs |
* MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs |
*/ |
/* |
* These variables either stay configured as initilalized, or are changed by |
* the MP configuration code. |
* |
* Pay special attention to the volatile keyword. Without it, gcc -O2 would |
* optimize the code too much and accesses to l_apic and io_apic, that must |
* always be 32-bit, would use byte oriented instructions. |
*/ |
volatile uint32_t *l_apic = (uint32_t *) 0xfee00000; |
volatile uint32_t *io_apic = (uint32_t *) 0xfec00000; |
uint32_t apic_id_mask = 0; |
static int apic_poll_errors(void); |
#ifdef LAPIC_VERBOSE |
static char *delmod_str[] = { |
"Fixed", |
"Lowest Priority", |
"SMI", |
"Reserved", |
"NMI", |
"INIT", |
"STARTUP", |
"ExtInt" |
}; |
static char *destmod_str[] = { |
"Physical", |
"Logical" |
}; |
static char *trigmod_str[] = { |
"Edge", |
"Level" |
}; |
static char *mask_str[] = { |
"Unmasked", |
"Masked" |
}; |
static char *delivs_str[] = { |
"Idle", |
"Send Pending" |
}; |
static char *tm_mode_str[] = { |
"One-shot", |
"Periodic" |
}; |
static char *intpol_str[] = { |
"Polarity High", |
"Polarity Low" |
}; |
#endif /* LAPIC_VERBOSE */ |
static void apic_spurious(int n, istate_t *istate); |
static void l_apic_timer_interrupt(int n, istate_t *istate); |
/** Initialize APIC on BSP. */ |
void apic_init(void) |
{ |
io_apic_id_t idreg; |
unsigned int i; |
exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); |
enable_irqs_function = io_apic_enable_irqs; |
disable_irqs_function = io_apic_disable_irqs; |
eoi_function = l_apic_eoi; |
/* |
* Configure interrupt routing. |
* IRQ 0 remains masked as the time signal is generated by l_apic's themselves. |
* Other interrupts will be forwarded to the lowest priority CPU. |
*/ |
io_apic_disable_irqs(0xffff); |
exc_register(VECTOR_CLK, "l_apic_timer", (iroutine) l_apic_timer_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
int pin; |
if ((pin = smp_irq_to_pin(i)) != -1) { |
io_apic_change_ioredtbl(pin, DEST_ALL, IVT_IRQBASE+i, LOPRI); |
} |
} |
/* |
* Ensure that io_apic has unique ID. |
*/ |
idreg.value = io_apic_read(IOAPICID); |
if ((1 << idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */ |
for (i = 0; i < APIC_ID_COUNT; i++) { |
if (!((1<<i) & apic_id_mask)) { |
idreg.apic_id = i; |
io_apic_write(IOAPICID, idreg.value); |
break; |
} |
} |
} |
/* |
* Configure the BSP's lapic. |
*/ |
l_apic_init(); |
l_apic_debug(); |
} |
/** APIC spurious interrupt handler. |
* |
* @param n Interrupt vector. |
* @param istate Interrupted state. |
*/ |
void apic_spurious(int n, istate_t *istate) |
{ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: APIC spurious interrupt\n", CPU->id); |
#endif |
} |
/** Poll for APIC errors. |
* |
* Examine Error Status Register and report all errors found. |
* |
* @return 0 on error, 1 on success. |
*/ |
int apic_poll_errors(void) |
{ |
esr_t esr; |
esr.value = l_apic[ESR]; |
if (esr.send_checksum_error) |
printf("Send Checksum Error\n"); |
if (esr.receive_checksum_error) |
printf("Receive Checksum Error\n"); |
if (esr.send_accept_error) |
printf("Send Accept Error\n"); |
if (esr.receive_accept_error) |
printf("Receive Accept Error\n"); |
if (esr.send_illegal_vector) |
printf("Send Illegal Vector\n"); |
if (esr.received_illegal_vector) |
printf("Received Illegal Vector\n"); |
if (esr.illegal_register_address) |
printf("Illegal Register Address\n"); |
return !esr.err_bitmap; |
} |
/** Send all CPUs excluding CPU IPI vector. |
* |
* @param vector Interrupt vector to be sent. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_broadcast_custom_ipi(uint8_t vector) |
{ |
icr_t icr; |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_FIXED; |
icr.destmod = DESTMOD_LOGIC; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_ALL_EXCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = vector; |
l_apic[ICRlo] = icr.lo; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
return apic_poll_errors(); |
} |
/** Universal Start-up Algorithm for bringing up the AP processors. |
* |
* @param apicid APIC ID of the processor to be brought up. |
* |
* @return 0 on failure, 1 on success. |
*/ |
int l_apic_send_init_ipi(uint8_t apicid) |
{ |
icr_t icr; |
int i; |
/* |
* Read the ICR register in and zero all non-reserved fields. |
*/ |
icr.lo = l_apic[ICRlo]; |
icr.hi = l_apic[ICRhi]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.shorthand = SHORTHAND_NONE; |
icr.vector = 0; |
icr.dest = apicid; |
l_apic[ICRhi] = icr.hi; |
l_apic[ICRlo] = icr.lo; |
/* |
* According to MP Specification, 20us should be enough to |
* deliver the IPI. |
*/ |
delay(20); |
if (!apic_poll_errors()) |
return 0; |
icr.lo = l_apic[ICRlo]; |
if (icr.delivs == DELIVS_PENDING) { |
#ifdef CONFIG_DEBUG |
printf("IPI is pending.\n"); |
#endif |
} |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
icr.vector = 0; |
l_apic[ICRlo] = icr.lo; |
/* |
* Wait 10ms as MP Specification specifies. |
*/ |
delay(10000); |
if (!is_82489DX_apic(l_apic[LAVR])) { |
/* |
* If this is not 82489DX-based l_apic we must send two STARTUP IPI's. |
*/ |
for (i = 0; i < 2; i++) { |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_STARTUP; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_ASSERT; |
icr.shorthand = SHORTHAND_NONE; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
delay(200); |
} |
} |
return apic_poll_errors(); |
} |
/** Initialize Local APIC. */ |
void l_apic_init(void) |
{ |
lvt_error_t error; |
lvt_lint_t lint; |
tpr_t tpr; |
svr_t svr; |
icr_t icr; |
tdcr_t tdcr; |
lvt_tm_t tm; |
ldr_t ldr; |
dfr_t dfr; |
uint32_t t1, t2; |
/* Initialize LVT Error register. */ |
error.value = l_apic[LVT_Err]; |
error.masked = true; |
l_apic[LVT_Err] = error.value; |
/* Initialize LVT LINT0 register. */ |
lint.value = l_apic[LVT_LINT0]; |
lint.masked = true; |
l_apic[LVT_LINT0] = lint.value; |
/* Initialize LVT LINT1 register. */ |
lint.value = l_apic[LVT_LINT1]; |
lint.masked = true; |
l_apic[LVT_LINT1] = lint.value; |
/* Task Priority Register initialization. */ |
tpr.value = l_apic[TPR]; |
tpr.pri_sc = 0; |
tpr.pri = 0; |
l_apic[TPR] = tpr.value; |
/* Spurious-Interrupt Vector Register initialization. */ |
svr.value = l_apic[SVR]; |
svr.vector = VECTOR_APIC_SPUR; |
svr.lapic_enabled = true; |
svr.focus_checking = true; |
l_apic[SVR] = svr.value; |
if (CPU->arch.family >= 6) |
enable_l_apic_in_msr(); |
/* Interrupt Command Register initialization. */ |
icr.lo = l_apic[ICRlo]; |
icr.delmod = DELMOD_INIT; |
icr.destmod = DESTMOD_PHYS; |
icr.level = LEVEL_DEASSERT; |
icr.shorthand = SHORTHAND_ALL_INCL; |
icr.trigger_mode = TRIGMOD_LEVEL; |
l_apic[ICRlo] = icr.lo; |
/* Timer Divide Configuration Register initialization. */ |
tdcr.value = l_apic[TDCR]; |
tdcr.div_value = DIVIDE_1; |
l_apic[TDCR] = tdcr.value; |
/* Program local timer. */ |
tm.value = l_apic[LVT_Tm]; |
tm.vector = VECTOR_CLK; |
tm.mode = TIMER_PERIODIC; |
tm.masked = false; |
l_apic[LVT_Tm] = tm.value; |
/* |
* Measure and configure the timer to generate timer |
* interrupt with period 1s/HZ seconds. |
*/ |
t1 = l_apic[CCRT]; |
l_apic[ICRT] = 0xffffffff; |
while (l_apic[CCRT] == t1) |
; |
t1 = l_apic[CCRT]; |
delay(1000000/HZ); |
t2 = l_apic[CCRT]; |
l_apic[ICRT] = t1-t2; |
/* Program Logical Destination Register. */ |
ldr.value = l_apic[LDR]; |
if (CPU->id < sizeof(CPU->id) * 8) /* size in bits */ |
ldr.id = (1 << CPU->id); |
l_apic[LDR] = ldr.value; |
/* Program Destination Format Register for Flat mode. */ |
dfr.value = l_apic[DFR]; |
dfr.model = MODEL_FLAT; |
l_apic[DFR] = dfr.value; |
} |
/** Local APIC End of Interrupt. */ |
void l_apic_eoi(void) |
{ |
l_apic[EOI] = 0; |
} |
/** Dump content of Local APIC registers. */ |
void l_apic_debug(void) |
{ |
#ifdef LAPIC_VERBOSE |
lvt_tm_t tm; |
lvt_lint_t lint; |
lvt_error_t error; |
printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id()); |
tm.value = l_apic[LVT_Tm]; |
printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]); |
lint.value = l_apic[LVT_LINT0]; |
printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
lint.value = l_apic[LVT_LINT1]; |
printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); |
error.value = l_apic[LVT_Err]; |
printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); |
#endif |
} |
/** Local APIC Timer Interrupt. |
* |
* @param n Interrupt vector number. |
* @param istate Interrupted state. |
*/ |
void l_apic_timer_interrupt(int n, istate_t *istate) |
{ |
l_apic_eoi(); |
clock(); |
} |
/** Get Local APIC ID. |
* |
* @return Local APIC ID. |
*/ |
uint8_t l_apic_id(void) |
{ |
l_apic_id_t idreg; |
idreg.value = l_apic[L_APIC_ID]; |
return idreg.apic_id; |
} |
/** Read from IO APIC register. |
* |
* @param address IO APIC register address. |
* |
* @return Content of the addressed IO APIC register. |
*/ |
uint32_t io_apic_read(uint8_t address) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
return io_apic[IOWIN]; |
} |
/** Write to IO APIC register. |
* |
* @param address IO APIC register address. |
* @param x Content to be written to the addressed IO APIC register. |
*/ |
void io_apic_write(uint8_t address, uint32_t x) |
{ |
io_regsel_t regsel; |
regsel.value = io_apic[IOREGSEL]; |
regsel.reg_addr = address; |
io_apic[IOREGSEL] = regsel.value; |
io_apic[IOWIN] = x; |
} |
/** Change some attributes of one item in I/O Redirection Table. |
* |
* @param pin IO APIC pin number. |
* @param dest Interrupt destination address. |
* @param v Interrupt vector to trigger. |
* @param flags Flags. |
*/ |
void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags) |
{ |
io_redirection_reg_t reg; |
int dlvr = DELMOD_FIXED; |
if (flags & LOPRI) |
dlvr = DELMOD_LOWPRI; |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.hi = io_apic_read(IOREDTBL + pin * 2 + 1); |
reg.dest = dest; |
reg.destmod = DESTMOD_LOGIC; |
reg.trigger_mode = TRIGMOD_EDGE; |
reg.intpol = POLARITY_HIGH; |
reg.delmod = dlvr; |
reg.intvec = v; |
io_apic_write(IOREDTBL + pin * 2, reg.lo); |
io_apic_write(IOREDTBL + pin * 2 + 1, reg.hi); |
} |
/** Mask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). |
*/ |
void io_apic_disable_irqs(uint16_t irqmask) |
{ |
io_redirection_reg_t reg; |
unsigned int i; |
int pin; |
for (i = 0; i < 16; i++) { |
if (irqmask & (1 << i)) { |
/* |
* Mask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.masked = true; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
/** Unmask IRQs in IO APIC. |
* |
* @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). |
*/ |
void io_apic_enable_irqs(uint16_t irqmask) |
{ |
unsigned int i; |
int pin; |
io_redirection_reg_t reg; |
for (i = 0; i < 16; i++) { |
if (irqmask & (1 << i)) { |
/* |
* Unmask the signal input in IO APIC if there is a |
* mapping for the respective IRQ number. |
*/ |
pin = smp_irq_to_pin(i); |
if (pin != -1) { |
reg.lo = io_apic_read(IOREDTBL + pin * 2); |
reg.masked = false; |
io_apic_write(IOREDTBL + pin*2, reg.lo); |
} |
} |
} |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/smp/ipi.c |
---|
0,0 → 1,48 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#ifdef CONFIG_SMP |
#include <smp/ipi.h> |
#include <arch/smp/apic.h> |
void ipi_broadcast_arch(int ipi) |
{ |
(void) l_apic_broadcast_custom_ipi((uint8_t) ipi); |
} |
#endif /* CONFIG_SMP */ |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/mm/tlb.c |
---|
0,0 → 1,75 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/tlb.h> |
#include <arch/mm/asid.h> |
#include <arch/asm.h> |
#include <arch/types.h> |
#include <arch/hypercall.h> |
/** Invalidate all entries in TLB. */ |
void tlb_invalidate_all(void) |
{ |
mmuext_op_t mmu_ext; |
mmu_ext.cmd = MMUEXT_TLB_FLUSH_LOCAL; |
xen_mmuext_op(&mmu_ext, 1, NULL, DOMID_SELF); |
} |
/** Invalidate all entries in TLB that belong to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
*/ |
void tlb_invalidate_asid(asid_t asid) |
{ |
tlb_invalidate_all(); |
} |
/** Invalidate TLB entries for specified page range belonging to specified address space. |
* |
* @param asid This parameter is ignored as the architecture doesn't support it. |
* @param page Address of the first page whose entry is to be invalidated. |
* @param cnt Number of entries to invalidate. |
*/ |
void tlb_invalidate_pages(asid_t asid, uintptr_t page, count_t cnt) |
{ |
unsigned int i; |
for (i = 0; i < cnt; i++) |
invlpg(page + i * PAGE_SIZE); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/mm/frame.c |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <mm/frame.h> |
#include <config.h> |
void physmem_print(void) |
{ |
printf("Base Size Reserved\n"); |
printf("---------- ---------- ---------\n"); |
printf("%#10x %#10x %#10x\n", PFN2ADDR(meminfo.start), |
PFN2ADDR(meminfo.size), PFN2ADDR(meminfo.reserved)); |
} |
void frame_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
/* The only memory zone */ |
zone_create(meminfo.start, meminfo.size, meminfo.start + meminfo.reserved, 0); |
frame_mark_unavailable(meminfo.start, meminfo.reserved); |
} |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/mm/page.c |
---|
0,0 → 1,86 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/mm/page.h> |
#include <genarch/mm/page_pt.h> |
#include <arch/mm/frame.h> |
#include <mm/frame.h> |
#include <mm/page.h> |
#include <mm/as.h> |
#include <arch/types.h> |
#include <align.h> |
#include <config.h> |
#include <func.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <debug.h> |
#include <memstr.h> |
#include <print.h> |
#include <interrupt.h> |
void page_arch_init(void) |
{ |
if (config.cpu_active == 1) { |
page_mapping_operations = &pt_mapping_operations; |
AS_KERNEL->genarch.page_table = (pte_t *) KA2PA(start_info.ptl0); |
} else |
SET_PTL0_ADDRESS_ARCH(AS_KERNEL->genarch.page_table); |
} |
void page_fault(int n, istate_t *istate) |
{ |
uintptr_t page; |
pf_access_t access; |
page = read_cr2(); |
if (istate->error_word & PFERR_CODE_RSVD) |
panic("Reserved bit set in page directory.\n"); |
if (istate->error_word & PFERR_CODE_RW) |
access = PF_ACCESS_WRITE; |
else |
access = PF_ACCESS_READ; |
if (as_page_fault(page, access, istate) == AS_PF_FAULT) { |
fault_if_from_uspace(istate, "Page fault: %#x", page); |
decode_istate(istate); |
printf("page fault address: %#x\n", page); |
panic("page fault\n"); |
} |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/mm/as.c |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_mm |
* @{ |
*/ |
/** @file |
* @ingroup ia32xen_mm |
*/ |
#include <arch/mm/as.h> |
#include <genarch/mm/page_pt.h> |
/** Architecture dependent address space init. */ |
void as_arch_init(void) |
{ |
as_operations = &as_pt_operations; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/ia32xen.c |
---|
0,0 → 1,218 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch.h> |
#include <main/main.h> |
#include <arch/types.h> |
#include <align.h> |
#include <arch/pm.h> |
#include <arch/drivers/xconsole.h> |
#include <arch/mm/page.h> |
#include <arch/context.h> |
#include <config.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <genarch/acpi/acpi.h> |
#include <arch/bios/bios.h> |
#include <interrupt.h> |
#include <arch/debugger.h> |
#include <proc/thread.h> |
#include <syscall/syscall.h> |
#include <console/console.h> |
#include <ddi/irq.h> |
start_info_t start_info; |
memzone_t meminfo; |
extern void xen_callback(void); |
extern void xen_failsafe_callback(void); |
void arch_pre_main(void) |
{ |
pte_t pte; |
memsetb((uintptr_t) &pte, sizeof(pte), 0); |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = ADDR2PFN((uintptr_t) start_info.shared_info); |
ASSERT(xen_update_va_mapping(&shared_info, pte, UVMF_INVLPG) == 0); |
if (!(start_info.flags & SIF_INITDOMAIN)) { |
/* Map console frame */ |
pte.present = 1; |
pte.writeable = 1; |
pte.frame_address = start_info.console.domU.mfn; |
ASSERT(xen_update_va_mapping(&console_page, pte, UVMF_INVLPG) == 0); |
} else |
start_info.console.domU.evtchn = 0; |
ASSERT(xen_set_callbacks(XEN_CS, xen_callback, XEN_CS, xen_failsafe_callback) == 0); |
/* Create identity mapping */ |
meminfo.start = ADDR2PFN(ALIGN_UP(KA2PA(start_info.ptl0), PAGE_SIZE)) + start_info.pt_frames; |
meminfo.size = start_info.frames - meminfo.start; |
meminfo.reserved = 0; |
uintptr_t pa; |
index_t last_ptl0 = 0; |
for (pa = PFN2ADDR(meminfo.start); pa < PFN2ADDR(meminfo.start + meminfo.size); pa += FRAME_SIZE) { |
uintptr_t va = PA2KA(pa); |
if ((PTL0_INDEX(va) != last_ptl0) && (GET_PTL1_FLAGS(start_info.ptl0, PTL0_INDEX(va)) & PAGE_NOT_PRESENT)) { |
/* New page directory entry needed */ |
uintptr_t tpa = PFN2ADDR(meminfo.start + meminfo.reserved); |
uintptr_t tva = PA2KA(tpa); |
memsetb(tva, PAGE_SIZE, 0); |
pte_t *tptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(tva))); |
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), 0); |
SET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va), tpa); |
SET_FRAME_ADDRESS(tptl3, PTL3_INDEX(tva), tpa); |
last_ptl0 = PTL0_INDEX(va); |
meminfo.reserved++; |
} |
pte_t *ptl3 = (pte_t *) PA2KA(GET_PTL1_ADDRESS(start_info.ptl0, PTL0_INDEX(va))); |
SET_FRAME_ADDRESS(ptl3, PTL3_INDEX(va), pa); |
SET_FRAME_FLAGS(ptl3, PTL3_INDEX(va), PAGE_PRESENT | PAGE_WRITE); |
} |
/* Put initial stack safely in the mapped area */ |
stack_safe = PA2KA(PFN2ADDR(meminfo.start + meminfo.reserved)); |
} |
void arch_pre_mm_init(void) |
{ |
pm_init(); |
if (config.cpu_active == 1) { |
interrupt_init(); |
// bios_init(); |
} |
} |
void arch_post_mm_init(void) |
{ |
if (config.cpu_active == 1) { |
/* Initialize IRQ routing */ |
irq_init(IRQ_COUNT, IRQ_COUNT); |
/* Video */ |
xen_console_init(); |
/* Enable debugger */ |
debugger_init(); |
/* Merge all memory zones to 1 big zone */ |
zone_merge_all(); |
} |
} |
void arch_post_cpu_init(void) |
{ |
} |
void arch_pre_smp_init(void) |
{ |
if (config.cpu_active == 1) { |
#ifdef CONFIG_SMP |
acpi_init(); |
#endif /* CONFIG_SMP */ |
} |
} |
void arch_post_smp_init(void) |
{ |
} |
void calibrate_delay_loop(void) |
{ |
// i8254_calibrate_delay_loop(); |
if (config.cpu_active == 1) { |
/* |
* This has to be done only on UP. |
* On SMP, i8254 is not used for time keeping and its interrupt pin remains masked. |
*/ |
// i8254_normal_operation(); |
} |
} |
/** Set thread-local-storage pointer |
* |
* TLS pointer is set in GS register. That means, the GS contains |
* selector, and the descriptor->base is the correct address. |
*/ |
unative_t sys_tls_set(unative_t addr) |
{ |
THREAD->arch.tls = addr; |
set_tls_desc(addr); |
return 0; |
} |
/** Acquire console back for kernel |
* |
*/ |
void arch_grab_console(void) |
{ |
} |
/** Return console to userspace |
* |
*/ |
void arch_release_console(void) |
{ |
} |
void arch_reboot(void) |
{ |
// TODO |
while (1); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/interrupt.c |
---|
0,0 → 1,248 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_interrupt |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/interrupt.h> |
#include <syscall/syscall.h> |
#include <print.h> |
#include <debug.h> |
#include <panic.h> |
#include <func.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <mm/tlb.h> |
#include <mm/as.h> |
#include <arch.h> |
#include <symtab.h> |
#include <proc/thread.h> |
#include <proc/task.h> |
#include <synch/spinlock.h> |
#include <arch/ddi/ddi.h> |
#include <ipc/sysipc.h> |
#include <interrupt.h> |
#include <ddi/irq.h> |
/* |
* Interrupt and exception dispatching. |
*/ |
void (* disable_irqs_function)(uint16_t irqmask) = NULL; |
void (* enable_irqs_function)(uint16_t irqmask) = NULL; |
void (* eoi_function)(void) = NULL; |
void decode_istate(istate_t *istate) |
{ |
char *symbol = get_symtab_entry(istate->eip); |
if (!symbol) |
symbol = ""; |
if (CPU) |
printf("----------------EXCEPTION OCCURED (cpu%d)----------------\n", CPU->id); |
else |
printf("----------------EXCEPTION OCCURED----------------\n"); |
printf("%%eip: %#x (%s)\n",istate->eip,symbol); |
printf("ERROR_WORD=%#x\n", istate->error_word); |
printf("%%cs=%#x,flags=%#x\n", istate->cs, istate->eflags); |
printf("%%eax=%#x, %%ecx=%#x, %%edx=%#x, %%esp=%#x\n", istate->eax,istate->ecx,istate->edx,&istate->stack[0]); |
#ifdef CONFIG_DEBUG_ALLREGS |
printf("%%esi=%#x, %%edi=%#x, %%ebp=%#x, %%ebx=%#x\n", istate->esi,istate->edi,istate->ebp,istate->ebx); |
#endif |
printf("stack: %#x, %#x, %#x, %#x\n", istate->stack[0], istate->stack[1], istate->stack[2], istate->stack[3]); |
printf(" %#x, %#x, %#x, %#x\n", istate->stack[4], istate->stack[5], istate->stack[6], istate->stack[7]); |
} |
static void trap_virtual_eoi(void) |
{ |
if (eoi_function) |
eoi_function(); |
else |
panic("no eoi_function\n"); |
} |
static void null_interrupt(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "unserviced interrupt: %d", n); |
decode_istate(istate); |
panic("unserviced interrupt: %d\n", n); |
} |
/** General Protection Fault. */ |
static void gp_fault(int n, istate_t *istate) |
{ |
if (TASK) { |
count_t ver; |
spinlock_lock(&TASK->lock); |
ver = TASK->arch.iomapver; |
spinlock_unlock(&TASK->lock); |
if (CPU->arch.iomapver_copy != ver) { |
/* |
* This fault can be caused by an early access |
* to I/O port because of an out-dated |
* I/O Permission bitmap installed on CPU. |
* Install the fresh copy and restart |
* the instruction. |
*/ |
io_perm_bitmap_install(); |
return; |
} |
fault_if_from_uspace(istate, "general protection fault"); |
} |
decode_istate(istate); |
panic("general protection fault\n"); |
} |
static void ss_fault(int n, istate_t *istate) |
{ |
fault_if_from_uspace(istate, "stack fault"); |
decode_istate(istate); |
panic("stack fault\n"); |
} |
static void simd_fp_exception(int n, istate_t *istate) |
{ |
uint32_t mxcsr; |
asm |
( |
"stmxcsr %0;\n" |
:"=m"(mxcsr) |
); |
fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx", |
(unative_t)mxcsr); |
decode_istate(istate); |
printf("MXCSR: %#zx\n",(unative_t)(mxcsr)); |
panic("SIMD FP exception(19)\n"); |
} |
static void nm_fault(int n, istate_t *istate) |
{ |
#ifdef CONFIG_FPU_LAZY |
scheduler_fpu_lazy_request(); |
#else |
fault_if_from_uspace(istate, "fpu fault"); |
panic("fpu fault"); |
#endif |
} |
#ifdef CONFIG_SMP |
static void tlb_shootdown_ipi(int n, istate_t *istate) |
{ |
trap_virtual_eoi(); |
tlb_shootdown_ipi_recv(); |
} |
#endif |
/** Handler of IRQ exceptions */ |
static void irq_interrupt(int n, istate_t *istate) |
{ |
ASSERT(n >= IVT_IRQBASE); |
int inum = n - IVT_IRQBASE; |
bool ack = false; |
ASSERT(inum < IRQ_COUNT); |
ASSERT((inum != IRQ_PIC_SPUR) && (inum != IRQ_PIC1)); |
irq_t *irq = irq_dispatch_and_lock(inum); |
if (irq) { |
/* |
* The IRQ handler was found. |
*/ |
if (irq->preack) { |
/* Send EOI before processing the interrupt */ |
trap_virtual_eoi(); |
ack = true; |
} |
irq->handler(irq, irq->arg); |
spinlock_unlock(&irq->lock); |
} else { |
/* |
* Spurious interrupt. |
*/ |
#ifdef CONFIG_DEBUG |
printf("cpu%d: spurious interrupt (inum=%d)\n", CPU->id, inum); |
#endif |
} |
if (!ack) |
trap_virtual_eoi(); |
} |
void interrupt_init(void) |
{ |
int i; |
for (i = 0; i < IVT_ITEMS; i++) |
exc_register(i, "null", (iroutine) null_interrupt); |
for (i = 0; i < IRQ_COUNT; i++) { |
if ((i != IRQ_PIC_SPUR) && (i != IRQ_PIC1)) |
exc_register(IVT_IRQBASE + i, "irq", (iroutine) irq_interrupt); |
} |
exc_register(7, "nm_fault", (iroutine) nm_fault); |
exc_register(12, "ss_fault", (iroutine) ss_fault); |
exc_register(13, "gp_fault", (iroutine) gp_fault); |
exc_register(19, "simd_fp", (iroutine) simd_fp_exception); |
#ifdef CONFIG_SMP |
exc_register(VECTOR_TLB_SHOOTDOWN_IPI, "tlb_shootdown", (iroutine) tlb_shootdown_ipi); |
#endif |
} |
void trap_virtual_enable_irqs(uint16_t irqmask) |
{ |
if (enable_irqs_function) |
enable_irqs_function(irqmask); |
else |
panic("no enable_irqs_function\n"); |
} |
void trap_virtual_disable_irqs(uint16_t irqmask) |
{ |
if (disable_irqs_function) |
disable_irqs_function(irqmask); |
else |
panic("no disable_irqs_function\n"); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/pm.c |
---|
0,0 → 1,206 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/pm.h> |
#include <config.h> |
#include <arch/types.h> |
#include <arch/interrupt.h> |
#include <arch/asm.h> |
#include <arch/context.h> |
#include <panic.h> |
#include <arch/mm/page.h> |
#include <mm/slab.h> |
#include <memstr.h> |
#include <interrupt.h> |
/* |
* Early ia32xen configuration functions and data structures. |
*/ |
/* |
* We have no use for segmentation so we set up flat mode. In this |
* mode, we use, for each privilege level, two segments spanning the |
* whole memory. One is for code and one is for data. |
* |
* One is for GS register which holds pointer to the TLS thread |
* structure in it's base. |
*/ |
descriptor_t gdt[GDT_ITEMS] = { |
/* NULL descriptor */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* KTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* KDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_KERNEL, 0xf, 0, 0, 1, 1, 0 }, |
/* UTEXT descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_CODE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* UDATA descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
/* TSS descriptor - set up will be completed later */ |
{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, |
/* TLS descriptor */ |
{ 0xffff, 0, 0, AR_PRESENT | AR_DATA | AR_WRITABLE | DPL_USER, 0xf, 0, 0, 1, 1, 0 }, |
}; |
static trap_info_t traps[IDT_ITEMS + 1]; |
static tss_t tss; |
tss_t *tss_p = NULL; |
/* gdtr is changed by kmp before next CPU is initialized */ |
ptr_16_32_t bootstrap_gdtr = { .limit = sizeof(gdt), .base = KA2PA((uintptr_t) gdt) }; |
ptr_16_32_t gdtr = { .limit = sizeof(gdt), .base = (uintptr_t) gdt }; |
void gdt_setbase(descriptor_t *d, uintptr_t base) |
{ |
d->base_0_15 = base & 0xffff; |
d->base_16_23 = ((base) >> 16) & 0xff; |
d->base_24_31 = ((base) >> 24) & 0xff; |
} |
void gdt_setlimit(descriptor_t *d, uint32_t limit) |
{ |
d->limit_0_15 = limit & 0xffff; |
d->limit_16_19 = (limit >> 16) & 0xf; |
} |
void tss_initialize(tss_t *t) |
{ |
memsetb((uintptr_t) t, sizeof(struct tss), 0); |
} |
static void trap(void) |
{ |
} |
void traps_init(void) |
{ |
index_t i; |
for (i = 0; i < IDT_ITEMS; i++) { |
traps[i].vector = i; |
if (i == VECTOR_SYSCALL) |
traps[i].flags = 3; |
else |
traps[i].flags = 0; |
traps[i].cs = XEN_CS; |
traps[i].address = trap; |
} |
traps[IDT_ITEMS].vector = 0; |
traps[IDT_ITEMS].flags = 0; |
traps[IDT_ITEMS].cs = 0; |
traps[IDT_ITEMS].address = NULL; |
} |
/* Clean IOPL(12,13) and NT(14) flags in EFLAGS register */ |
static void clean_IOPL_NT_flags(void) |
{ |
// asm volatile ( |
// "pushfl\n" |
// "pop %%eax\n" |
// "and $0xffff8fff, %%eax\n" |
// "push %%eax\n" |
// "popfl\n" |
// : : : "eax" |
// ); |
} |
/* Clean AM(18) flag in CR0 register */ |
static void clean_AM_flag(void) |
{ |
// asm volatile ( |
// "mov %%cr0, %%eax\n" |
// "and $0xfffbffff, %%eax\n" |
// "mov %%eax, %%cr0\n" |
// : : : "eax" |
// ); |
} |
void pm_init(void) |
{ |
descriptor_t *gdt_p = (descriptor_t *) gdtr.base; |
// gdtr_load(&gdtr); |
if (config.cpu_active == 1) { |
traps_init(); |
xen_set_trap_table(traps); |
/* |
* NOTE: bootstrap CPU has statically allocated TSS, because |
* the heap hasn't been initialized so far. |
*/ |
tss_p = &tss; |
} else { |
tss_p = (tss_t *) malloc(sizeof(tss_t), FRAME_ATOMIC); |
if (!tss_p) |
panic("could not allocate TSS\n"); |
} |
// tss_initialize(tss_p); |
gdt_p[TSS_DES].access = AR_PRESENT | AR_TSS | DPL_KERNEL; |
gdt_p[TSS_DES].special = 1; |
gdt_p[TSS_DES].granularity = 0; |
gdt_setbase(&gdt_p[TSS_DES], (uintptr_t) tss_p); |
gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE - 1); |
/* |
* As of this moment, the current CPU has its own GDT pointing |
* to its own TSS. We just need to load the TR register. |
*/ |
// tr_load(selector(TSS_DES)); |
clean_IOPL_NT_flags(); /* Disable I/O on nonprivileged levels and clear NT flag. */ |
clean_AM_flag(); /* Disable alignment check */ |
} |
void set_tls_desc(uintptr_t tls) |
{ |
ptr_16_32_t cpugdtr; |
descriptor_t *gdt_p; |
gdtr_store(&cpugdtr); |
gdt_p = (descriptor_t *) cpugdtr.base; |
gdt_setbase(&gdt_p[TLS_DES], tls); |
/* Reload gdt register to update GS in CPU */ |
gdtr_load(&cpugdtr); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/boot/boot.S |
---|
0,0 → 1,102 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include <arch/mm/page.h> |
#include <arch/hypercall.h> |
#define ELFNOTE(name, type, desctype, descval) \ |
.section .note.name; \ |
.align 4; \ |
.long 2f - 1f; \ |
.long 4f - 3f; \ |
.long type; \ |
1:.asciz #name; \ |
2:.align 4; \ |
3:desctype descval; \ |
4:.align 4 |
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_OS, .asciz, "HelenOS") |
ELFNOTE(Xen, XEN_ELFNOTE_GUEST_VERSION, .asciz, RELEASE) |
ELFNOTE(Xen, XEN_ELFNOTE_XEN_VERSION, .asciz, "xen-3.0") |
ELFNOTE(Xen, XEN_ELFNOTE_VIRT_BASE, .long, PA2KA(BOOT_OFFSET)) |
ELFNOTE(Xen, XEN_ELFNOTE_PADDR_OFFSET, .long, 0) |
ELFNOTE(Xen, XEN_ELFNOTE_ENTRY, .long, kernel_image_start) |
ELFNOTE(Xen, XEN_ELFNOTE_HYPERCALL_PAGE, .long, hypercall_page) |
ELFNOTE(Xen, XEN_ELFNOTE_FEATURES, .asciz, "auto_translated_physmap|supervisor_mode_kernel") |
ELFNOTE(Xen, XEN_ELFNOTE_PAE_MODE, .asciz, "no") |
ELFNOTE(Xen, XEN_ELFNOTE_LOADER, .asciz, "generic") |
.text |
.code32 |
.align 4 |
.global kernel_image_start |
kernel_image_start: |
# copy start_info (esi initialized by Xen) |
movl $start_info, %edi |
movl $START_INFO_SIZE >> 2, %ecx |
cld |
rep movsb |
# switch to temporal kernel stack |
movl $kernel_stack, %esp |
call arch_pre_main |
call main_bsp # never returns |
cli |
hlt |
kernel_stack_bottom: |
.space TEMP_STACK_SIZE |
kernel_stack: |
.section K_TEXT_START, "aw", @progbits |
.global hypercall_page |
.org 0 |
hypercall_page: |
.space PAGE_SIZE |
.global shared_info |
.org 0x1000 |
shared_info: |
.space PAGE_SIZE |
.global console_page |
.org 0x2000 |
console_page: |
.space PAGE_SIZE |
# Xen 3.0.3 ELF loader is somehow buggy |
# thus this workaround |
.global dummy_fill |
dummy_fill: |
.space (1024 * 1024) |
/branches/dd/kernel/arch/ia32xen/src/asm.S |
---|
0,0 → 1,124 |
# |
# Copyright (c) 2001-2004 Jakub Jermar |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## very low and hardware-level functions |
# Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word |
# and 1 means interrupt with error word |
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00 |
.text |
.global xen_callback |
.global xen_failsafe_callback |
.global enable_l_apic_in_msr |
.global memcpy |
.global memcpy_from_uspace |
.global memcpy_from_uspace_failover_address |
.global memcpy_to_uspace |
.global memcpy_to_uspace_failover_address |
xen_callback: |
iret |
xen_failsafe_callback: |
iret |
#define MEMCPY_DST 4 |
#define MEMCPY_SRC 8 |
#define MEMCPY_SIZE 12 |
/** Copy memory to/from userspace. |
* |
* This is almost conventional memcpy(). |
* The difference is that there is a failover part |
* to where control is returned from a page fault |
* if the page fault occurs during copy_from_uspace() |
* or copy_to_uspace(). |
* |
* @param MEMCPY_DST(%esp) Destination address. |
* @param MEMCPY_SRC(%esp) Source address. |
* @param MEMCPY_SIZE(%esp) Size. |
* |
* @return MEMCPY_SRC(%esp) on success and 0 on failure. |
*/ |
memcpy: |
memcpy_from_uspace: |
memcpy_to_uspace: |
movl %edi, %edx /* save %edi */ |
movl %esi, %eax /* save %esi */ |
movl MEMCPY_SIZE(%esp), %ecx |
shrl $2, %ecx /* size / 4 */ |
movl MEMCPY_DST(%esp), %edi |
movl MEMCPY_SRC(%esp), %esi |
rep movsl /* copy as much as possible word by word */ |
movl MEMCPY_SIZE(%esp), %ecx |
andl $3, %ecx /* size % 4 */ |
jz 0f |
rep movsb /* copy the rest byte by byte */ |
0: |
movl %edx, %edi |
movl %eax, %esi |
movl MEMCPY_SRC(%esp), %eax /* MEMCPY_SRC(%esp), success */ |
ret |
/* |
* We got here from as_page_fault() after the memory operations |
* above had caused a page fault. |
*/ |
memcpy_from_uspace_failover_address: |
memcpy_to_uspace_failover_address: |
movl %edx, %edi |
movl %eax, %esi |
xorl %eax, %eax /* return 0, failure */ |
ret |
## Enable local APIC |
# |
# Enable local APIC in MSR. |
# |
enable_l_apic_in_msr: |
push %eax |
movl $0x1b, %ecx |
rdmsr |
orl $(1<<11),%eax |
orl $(0xfee00000),%eax |
wrmsr |
pop %eax |
ret |
/branches/dd/kernel/arch/ia32xen/src/proc/scheduler.c |
---|
0,0 → 1,81 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/scheduler.h> |
#include <cpu.h> |
#include <proc/task.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/context.h> /* SP_DELTA */ |
#include <arch/debugger.h> |
#include <arch/pm.h> |
#include <arch/asm.h> |
#include <arch/ddi/ddi.h> |
/** Perform ia32 specific tasks needed before the new task is run. |
* |
* Interrupts are disabled. |
*/ |
void before_task_runs_arch(void) |
{ |
// io_perm_bitmap_install(); |
} |
/** Perform ia32 specific tasks needed before the new thread is scheduled. |
* |
* THREAD is locked and interrupts are disabled. |
*/ |
void before_thread_runs_arch(void) |
{ |
CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE-SP_DELTA]; |
CPU->arch.tss->ss0 = selector(KDATA_DES); |
/* Set up TLS in GS register */ |
// set_tls_desc(THREAD->arch.tls); |
#ifdef CONFIG_DEBUG_AS_WATCHPOINT |
/* Set watchpoint on AS to ensure that nobody sets it to zero */ |
if (CPU->id < BKPOINTS_MAX) |
breakpoint_add(&((the_t *) THREAD->kstack)->as, |
BKPOINT_WRITE | BKPOINT_CHECK_ZERO, |
CPU->id); |
#endif |
} |
void after_thread_ran_arch(void) |
{ |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/proc/task.c |
---|
0,0 → 1,61 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/task.h> |
#include <arch/types.h> |
#include <adt/bitmap.h> |
#include <mm/slab.h> |
/** Perform ia32 specific task initialization. |
* |
* @param t Task to be initialized. |
*/ |
void task_create_arch(task_t *t) |
{ |
t->arch.iomapver = 0; |
bitmap_initialize(&t->arch.iomap, NULL, 0); |
} |
/** Perform ia32 specific task destruction. |
* |
* @param t Task to be initialized. |
*/ |
void task_destroy_arch(task_t *t) |
{ |
if (t->arch.iomap.map) |
free(t->arch.iomap.map); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/proc/thread.c |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen_proc |
* @{ |
*/ |
/** @file |
*/ |
#include <proc/thread.h> |
/** Perform ia32xen specific thread initialization. |
* |
* @param t Thread to be initialized. |
*/ |
void thread_create_arch(thread_t *t) |
{ |
t->arch.tls = 0; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/userspace.c |
---|
0,0 → 1,89 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** @file |
*/ |
#include <userspace.h> |
#include <arch/pm.h> |
#include <arch/types.h> |
#include <arch.h> |
#include <proc/uarg.h> |
#include <mm/as.h> |
/** Enter userspace |
* |
* Change CPU protection level to 3, enter userspace. |
* |
*/ |
void userspace(uspace_arg_t *kernel_uarg) |
{ |
uint32_t ipl = interrupts_disable(); |
asm volatile ( |
/* |
* Clear nested task flag. |
*/ |
"pushfl\n" |
"pop %%eax\n" |
"and $0xffffbfff, %%eax\n" |
"push %%eax\n" |
"popfl\n" |
/* Set up GS register (TLS) */ |
"movl %6, %%gs\n" |
"pushl %0\n" |
"pushl %1\n" |
"pushl %2\n" |
"pushl %3\n" |
"pushl %4\n" |
"movl %5, %%eax\n" |
"iret\n" |
: |
: "i" (selector(UDATA_DES) | PL_USER), |
"r" (kernel_uarg->uspace_stack + THREAD_STACK_SIZE), |
"r" (ipl), |
"i" (selector(UTEXT_DES) | PL_USER), |
"r" (kernel_uarg->uspace_entry), |
"r" (kernel_uarg->uspace_uarg), |
"r" (selector(TLS_DES)) |
: "eax" |
); |
/* Unreachable */ |
for(;;) |
; |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/drivers/xconsole.c |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup ia32xen |
* @{ |
*/ |
/** |
* @file |
* @brief ia32xen console driver. |
*/ |
#include <arch/drivers/xconsole.h> |
#include <putchar.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <arch/hypercall.h> |
#define MASK_INDEX(index, ring) ((index) & (sizeof(ring) - 1)) |
static void xen_putchar(chardev_t *d, const char ch); |
chardev_t xen_console; |
static chardev_operations_t xen_ops = { |
.write = xen_putchar |
}; |
void xen_console_init(void) |
{ |
chardev_initialize("xen_out", &xen_console, &xen_ops); |
stdout = &xen_console; |
} |
void xen_putchar(chardev_t *d, const char ch) |
{ |
if (start_info.console.domU.evtchn != 0) { |
uint32_t cons = console_page.out_cons; |
uint32_t prod = console_page.out_prod; |
memory_barrier(); |
if ((prod - cons) > sizeof(console_page.out)) |
return; |
if (ch == '\n') |
console_page.out[MASK_INDEX(prod++, console_page.out)] = '\r'; |
console_page.out[MASK_INDEX(prod++, console_page.out)] = ch; |
write_barrier(); |
console_page.out_prod = prod; |
xen_notify_remote(start_info.console.domU.evtchn); |
} else |
xen_console_io(CONSOLE_IO_WRITE, 1, &ch); |
} |
/** @} |
*/ |
/branches/dd/kernel/arch/ia32xen/src/fpu_context.c |
---|
0,0 → 1,0 |
link ../../ia32/src/fpu_context.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/debug |
---|
0,0 → 1,0 |
link ../../ia32/src/debug |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/cpu |
---|
0,0 → 1,0 |
link ../../ia32/src/cpu |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/bios |
---|
0,0 → 1,0 |
link ../../ia32/src/bios |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/delay.s |
---|
0,0 → 1,0 |
link ../../ia32/src/delay.s |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/ddi |
---|
0,0 → 1,0 |
link ../../ia32/src/ddi |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/debugger.c |
---|
0,0 → 1,0 |
link ../../ia32/src/debugger.c |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/src/atomic.S |
---|
0,0 → 1,0 |
link ../../ia32/src/atomic.S |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/kernel/arch/ia32xen/_link.ld.in |
---|
0,0 → 1,45 |
/** ia32xen linker script |
*/ |
#include <arch/hypercall.h> |
#include <arch/mm/page.h> |
ENTRY(kernel_image_start) |
PHDRS { |
image PT_LOAD FLAGS(7); /* RWE */ |
note PT_NOTE FLAGS(4); /* R__ */ |
} |
SECTIONS { |
.image PA2KA(BOOT_OFFSET): AT (BOOT_OFFSET) { |
ktext_start = .; |
*(K_TEXT_START); |
*(.text); |
ktext_end = .; |
kdata_start = .; |
*(.data); /* initialized data */ |
*(.rodata*); /* string literals */ |
*(COMMON); /* global variables */ |
hardcoded_load_address = .; |
LONG(PA2KA(0)); |
hardcoded_ktext_size = .; |
LONG(ktext_end - ktext_start); |
hardcoded_kdata_size = .; |
LONG(kdata_end - kdata_start); |
symbol_table = .; |
*(symtab.*); /* Symbol table, must be LAST symbol! */ |
*(.bss); /* uninitialized static variables */ |
kdata_end = .; |
} :image |
.notes : { |
*(.note.Xen); |
} :note |
/DISCARD/ : { |
*(.note.GNU-stack); |
*(.comment); |
} |
} |
/branches/dd/kernel/kernel.config |
---|
0,0 → 1,178 |
# |
# Copyright (c) 2006 Ondrej Palkovsky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## General configuration directives |
# Architecture |
@ "amd64" AMD64/Intel EM64T |
@ "arm32" ARM 32-bit |
@ "ia32" Intel IA-32 |
@ "ia32xen" Intel IA-32 on Xen hypervisor |
@ "ia64" Intel IA-64 |
@ "mips32" MIPS 32-bit |
@ "ppc32" PowerPC 32-bit |
@ "ppc64" PowerPC 64-bit |
@ "sparc64" Sun UltraSPARC 64-bit |
! ARCH (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=amd64|ARCH=ia32|ARCH=ia32xen] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
! [ARCH=ia64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=sparc64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
! [ARCH=arm32|ARCH=mips32|ARCH=ppc32|ARCH=ppc64] COMPILER (choice) |
# CPU type |
@ "pentium4" Pentium 4 |
@ "pentium3" Pentium 3 |
@ "core" Core Solo/Duo |
@ "athlon-xp" Athlon XP |
@ "athlon-mp" Athlon MP |
! [ARCH=ia32|ARCH=ia32xen] MACHINE (choice) |
# CPU type |
@ "opteron" Opteron |
! [ARCH=amd64] MACHINE (choice) |
# Machine type |
@ "msim" MSIM Simulator |
@ "simics" Virtutech Simics simulator |
@ "lgxemul" GXEmul Little Endian |
@ "bgxemul" GXEmul Big Endian |
@ "indy" SGI Indy |
! [ARCH=mips32] MACHINE (choice) |
# Machine type |
@ "gxemul_testarm" GXEmul testarm |
! [ARCH=arm32] MACHINE (choice) |
# Framebuffer support |
! [(ARCH=mips32&MACHINE=lgxemul)|(ARCH=mips32&MACHINE=bgxemul)|(ARCH=ia32)|(ARCH=amd64)|(ARCH=arm32&MACHINE=gxemul_testarm)] CONFIG_FB (y/n) |
# Framebuffer width |
@ "640" |
@ "800" |
@ "1024" |
@ "1152" |
@ "1280" |
@ "1400" |
@ "1440" |
@ "1600" |
@ "2048" |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_WIDTH (choice) |
# Framebuffer height |
@ "480" |
@ "600" |
@ "768" |
@ "852" |
@ "900" |
@ "960" |
@ "1024" |
@ "1050" |
@ "1200" |
@ "1536" |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_HEIGHT (choice) |
# Framebuffer depth |
@ "8" |
@ "16" |
@ "24" |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice) |
# Support for SMP |
! [ARCH=ia32|ARCH=amd64|ARCH=ia32xen|ARCH=sparc64] CONFIG_SMP (y/n) |
# Improved support for hyperthreading |
! [(ARCH=ia32|ARCH=amd64|ARCH=ia32xen)&CONFIG_SMP=y] CONFIG_HT (y/n) |
# Simics BIOS AP boot fix |
! [(ARCH=ia32|ARCH=amd64)&CONFIG_SMP=y] CONFIG_SIMICS_FIX (y/n) |
# Lazy FPU context switching |
! [(ARCH=mips32&MACHINE!=msim&MACHINE!=simics)|ARCH=amd64|ARCH=ia32|ARCH=ia64|ARCH=sparc64|ARCH=ia32xen] CONFIG_FPU_LAZY (y/n) |
# Use VHPT |
! [ARCH=ia64] CONFIG_VHPT (n/y) |
# Use TSB |
! [ARCH=sparc64] CONFIG_TSB (y/n) |
# Support for Z8530 serial port |
! [ARCH=sparc64] CONFIG_Z8530 (y/n) |
# Support for NS16550 serial port |
! [ARCH=sparc64] CONFIG_NS16550 (y/n) |
# Virtually indexed D-cache support |
! [ARCH=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n) |
## Debugging configuration directives |
# General debuging and assert checking |
! CONFIG_DEBUG (y/n) |
# Deadlock detection support for spinlocks |
! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n) |
# Watchpoint on rewriting AS with zero |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=ia32|ARCH=ia32xen)] CONFIG_DEBUG_AS_WATCHPOINT (y/n) |
# Save all interrupt registers |
! [CONFIG_DEBUG=y&(ARCH=amd64|ARCH=mips32|ARCH=ia32|ARCH=ia32xen)] CONFIG_DEBUG_ALLREGS (y/n) |
## Run-time configuration directives |
# Compile kernel tests |
! CONFIG_TEST (y/n) |
## Experimental features |
# Enable experimental features |
! CONFIG_EXPERIMENTAL (n/y) |
/branches/dd/kernel/Makefile |
---|
30,28 → 30,24 |
## Include configuration |
# |
include ../version |
-include ../Makefile.config |
-include ../config.defs |
-include ../version |
-include Makefile.config |
INCLUDES = generic/include |
OPTIMIZATION = 3 |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
## Common compiler flags |
# |
DEFS = -DKERNEL -DRELEASE=$(RELEASE) "-DNAME=$(NAME)" |
DEFS = -D$(ARCH) -DARCH=\"$(ARCH)\" -DRELEASE=\"$(RELEASE)\" "-DNAME=\"$(NAME)\"" \ |
-DKERNEL |
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \ |
-fno-builtin -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \ |
-nostdlib -nostdinc -pipe |
GCC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \ |
-fno-builtin -fomit-frame-pointer -Wall -Wextra -Wno-unused-parameter -Wmissing-prototypes -Werror \ |
-nostdlib -nostdinc |
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) -imacros ../config.h \ |
-fno-builtin -Wall -Wmissing-prototypes -Werror \ |
ICC_CFLAGS = -I$(INCLUDES) -O$(OPTIMIZATION) \ |
-fno-builtin -fomit-frame-pointer -Wall -Wmissing-prototypes -Werror \ |
-nostdlib -nostdinc \ |
-wd170 |
62,7 → 58,15 |
LFLAGS = -M |
AFLAGS = |
-include arch/$(KARCH)/Makefile.inc |
ifdef REVISION |
DEFS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
-include arch/$(ARCH)/Makefile.inc |
-include genarch/Makefile.inc |
## The at-sign |
80,6 → 84,68 |
# |
SYMTAB_SECTION=".section symtab.data, \"a\", $(ATSIGN)progbits;" |
## Setup kernel configuration |
# |
ifeq ($(CONFIG_DEBUG),y) |
DEFS += -DCONFIG_DEBUG |
endif |
ifeq ($(CONFIG_DEBUG_SPINLOCK),y) |
DEFS += -DCONFIG_DEBUG_SPINLOCK |
endif |
ifeq ($(CONFIG_DEBUG_AS_WATCHPOINT),y) |
DEFS += -DCONFIG_DEBUG_AS_WATCHPOINT |
endif |
ifeq ($(CONFIG_FPU_LAZY),y) |
DEFS += -DCONFIG_FPU_LAZY |
endif |
ifeq ($(CONFIG_DEBUG_ALLREGS),y) |
DEFS += -DCONFIG_DEBUG_ALLREGS |
endif |
ifeq ($(CONFIG_VHPT),y) |
DEFS += -DCONFIG_VHPT |
endif |
ifeq ($(CONFIG_TSB),y) |
DEFS += -DCONFIG_TSB |
endif |
ifeq ($(CONFIG_Z8530),y) |
DEFS += -DCONFIG_Z8530 |
endif |
ifeq ($(CONFIG_NS16550),y) |
DEFS += -DCONFIG_NS16550 |
endif |
ifeq ($(CONFIG_VIRT_IDX_DCACHE),y) |
DEFS += -DCONFIG_VIRT_IDX_DCACHE |
endif |
ifeq ($(CONFIG_FB),y) |
ifeq ($(ARCH),ia32) |
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH) |
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT) |
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP) |
endif |
ifeq ($(ARCH),amd64) |
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH) |
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT) |
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP) |
endif |
ifeq ($(ARCH),ia32xen) |
DEFS += -DCONFIG_VESA_WIDTH=$(CONFIG_VESA_WIDTH) |
DEFS += -DCONFIG_VESA_HEIGHT=$(CONFIG_VESA_HEIGHT) |
DEFS += -DCONFIG_VESA_BPP=$(CONFIG_VESA_BPP) |
endif |
endif |
## Simple detection for the type of the host system |
# |
HOST = $(shell uname) |
104,7 → 170,6 |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
LIBDIR = /usr/lib |
CFLAGS = $(GCC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),icc_native) |
116,7 → 181,6 |
OBJDUMP = objdump |
LIBDIR = /usr/lib |
CFLAGS = $(ICC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),suncc_native) |
128,8 → 192,6 |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
LIBDIR = /usr/lib |
CFLAGS = $(SUNCC_CFLAGS) |
DEFS += $(CONFIG_DEFS) |
DEPEND_DEFS = $(DEFS) |
endif |
ifeq ($(COMPILER),gcc_cross) |
141,7 → 203,6 |
OBJDUMP = $(TOOLCHAIN_DIR)/bin/$(TARGET)-objdump |
LIBDIR = $(TOOLCHAIN_DIR)/lib |
CFLAGS = $(GCC_CFLAGS) |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
## Generic kernel sources |
155,6 → 216,9 |
generic/src/adt/list.c \ |
generic/src/console/chardev.c \ |
generic/src/console/console.c \ |
generic/src/console/kconsole.c \ |
generic/src/console/klog.c \ |
generic/src/console/cmd.c \ |
generic/src/cpu/cpu.c \ |
generic/src/ddi/ddi.c \ |
generic/src/ddi/irq.c \ |
165,7 → 229,6 |
generic/src/main/uinit.c \ |
generic/src/main/version.c \ |
generic/src/main/shutdown.c \ |
generic/src/proc/program.c \ |
generic/src/proc/scheduler.c \ |
generic/src/proc/thread.c \ |
generic/src/proc/task.c \ |
185,7 → 248,6 |
generic/src/lib/func.c \ |
generic/src/lib/memstr.c \ |
generic/src/lib/sort.c \ |
generic/src/lib/string.c \ |
generic/src/lib/elf.c \ |
generic/src/lib/rd.c \ |
generic/src/printf/printf_core.c \ |
205,7 → 267,6 |
generic/src/synch/rwlock.c \ |
generic/src/synch/mutex.c \ |
generic/src/synch/semaphore.c \ |
generic/src/synch/smc.c \ |
generic/src/synch/waitq.c \ |
generic/src/synch/futex.c \ |
generic/src/smp/ipi.c \ |
217,30 → 278,11 |
generic/src/security/cap.c \ |
generic/src/sysinfo/sysinfo.c |
## Kernel console support |
# |
ifeq ($(CONFIG_KCONSOLE),y) |
GENERIC_SOURCES += \ |
generic/src/console/kconsole.c \ |
generic/src/console/cmd.c |
endif |
## Udebug interface sources |
# |
ifeq ($(CONFIG_UDEBUG),y) |
GENERIC_SOURCES += \ |
generic/src/ipc/kbox.c \ |
generic/src/udebug/udebug.c \ |
generic/src/udebug/udebug_ops.c \ |
generic/src/udebug/udebug_ipc.c |
endif |
## Test sources |
# |
ifeq ($(CONFIG_TEST),y) |
DEFS += -DCONFIG_TEST |
CFLAGS += -Itest/ |
GENERIC_SOURCES += \ |
test/test.c \ |
247,12 → 289,17 |
test/atomic/atomic1.c \ |
test/btree/btree1.c \ |
test/avltree/avltree1.c \ |
test/debug/mips1.c \ |
test/fault/fault1.c \ |
test/fpu/fpu1.c \ |
test/fpu/sse1.c \ |
test/fpu/mips2.c \ |
test/mm/falloc1.c \ |
test/mm/falloc2.c \ |
test/mm/mapping1.c \ |
test/mm/slab1.c \ |
test/mm/slab2.c \ |
test/mm/purge1.c \ |
test/synch/rwlock1.c \ |
test/synch/rwlock2.c \ |
test/synch/rwlock3.c \ |
263,76 → 310,41 |
test/print/print1.c \ |
test/thread/thread1.c \ |
test/sysinfo/sysinfo1.c |
ifeq ($(KARCH),mips32) |
GENERIC_SOURCES += test/debug/mips1.c |
else |
GENERIC_SOURCES += test/debug/mips1_skip.c |
endif |
ifeq ($(KARCH),ia64) |
GENERIC_SOURCES += test/mm/purge1.c |
else |
GENERIC_SOURCES += test/mm/purge1_skip.c |
endif |
ifeq ($(CONFIG_FPU),y) |
ifeq ($(KARCH),ia32) |
TEST_FPU1 = y |
TEST_SSE1 = y |
GENERIC_SOURCES += test/fpu/fpu1_x86.c |
endif |
ifeq ($(KARCH),amd64) |
TEST_FPU1 = y |
TEST_SSE1 = y |
GENERIC_SOURCES += test/fpu/fpu1_x86.c |
endif |
ifeq ($(KARCH),ia64) |
TEST_FPU1 = y |
GENERIC_SOURCES += test/fpu/fpu1_ia64.c |
endif |
ifeq ($(KARCH),mips32) |
TEST_MIPS2 = y |
endif |
endif |
ifneq ($(TEST_FPU1),y) |
GENERIC_SOURCES += test/fpu/fpu1_skip.c |
endif |
ifeq ($(TEST_SSE1),y) |
GENERIC_SOURCES += test/fpu/sse1.c |
else |
GENERIC_SOURCES += test/fpu/sse1_skip.c |
endif |
ifeq ($(TEST_MIPS2),y) |
GENERIC_SOURCES += test/fpu/mips2.c |
else |
GENERIC_SOURCES += test/fpu/mips2_skip.c |
endif |
endif |
## Experimental features |
# |
ifeq ($(CONFIG_EXPERIMENTAL),y) |
GENERIC_SOURCES += generic/src/lib/objc_ext.c \ |
generic/src/lib/objc.c |
EXTRA_OBJECTS = $(LIBDIR)/libobjc.a |
EXTRA_FLAGS += -x objective-c |
endif |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES))) |
.PHONY: all build clean archlinks depend disasm |
.PHONY: all build config distclean clean archlinks depend disasm |
all: ../Makefile.config ../config.h ../config.defs |
-rm Makefile.depend |
all: |
../tools/config.py kernel.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(MACHINE) |
$(MAKE) -C . build |
build: kernel.bin disasm |
config: |
-rm Makefile.depend |
../tools/config.py kernel.config |
-include Makefile.depend |
distclean: clean |
-rm Makefile.config |
clean: |
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(KARCH)/_link.ld |
-rm -f kernel.bin kernel.raw kernel.map kernel.map.pre kernel.objdump kernel.disasm generic/src/debug/real_map.bin Makefile.depend* generic/include/arch generic/include/genarch arch/$(ARCH)/_link.ld |
find generic/src/ arch/*/src/ genarch/src/ test/ -name '*.o' -follow -exec rm \{\} \; |
for arch in arch/* ; do \ |
[ -e $$arch/_link.ld ] && rm $$arch/_link.ld 2>/dev/null ; \ |
339,24 → 351,24 |
done ; exit 0 |
archlinks: |
ln -sfn ../../arch/$(KARCH)/include/ generic/include/arch |
ln -sfn ../../arch/$(ARCH)/include/ generic/include/arch |
ln -sfn ../../genarch/include/ generic/include/genarch |
depend: archlinks |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
arch/$(KARCH)/_link.ld: arch/$(KARCH)/_link.ld.in |
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in |
$(GCC) $(DEFS) $(GCC_CFLAGS) -D__ASM__ -D__LINKER__ -E -x c $< | grep -v "^\#" > $@ |
generic/src/debug/real_map.bin: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) |
generic/src/debug/real_map.bin: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) |
echo $(SYMTAB_SECTION) | $(AS) $(AFLAGS) -o generic/src/debug/empty_map.o |
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre |
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/empty_map.o -o $@ -Map kernel.map.pre |
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump |
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin |
# Do it once again, this time to get correct even the symbols |
# on architectures, that have bss after symtab |
echo $(SYMTAB_SECTION)" .incbin \"$@\"" | $(AS) $(AFLAGS) -o generic/src/debug/sizeok_map.o |
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre |
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/sizeok_map.o -o $@ -Map kernel.map.pre |
$(OBJDUMP) -t $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) > kernel.objdump |
tools/genmap.py kernel.map.pre kernel.objdump generic/src/debug/real_map.bin |
363,8 → 375,8 |
generic/src/debug/real_map.o: generic/src/debug/real_map.bin |
echo $(SYMTAB_SECTION)" .incbin \"$<\"" | $(AS) $(AFLAGS) -o $@ |
kernel.raw: depend arch/$(KARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o |
$(LD) -T arch/$(KARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map |
kernel.raw: depend arch/$(ARCH)/_link.ld $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) generic/src/debug/real_map.o |
$(LD) -T arch/$(ARCH)/_link.ld $(LFLAGS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(GENERIC_OBJECTS) $(EXTRA_OBJECTS) generic/src/debug/real_map.o -o $@ -Map kernel.map |
kernel.bin: kernel.raw |
$(OBJCOPY) -O $(BFD) kernel.raw kernel.bin |
378,15 → 390,5 |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
# |
# The FPU tests are the only objects for which we allow the compiler to generate |
# FPU instructions. |
# |
test/fpu/%.o: test/fpu/%.c |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) -c $< -o $@ |
# |
# Ordinary objects. |
# |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) $(EXTRA_FLAGS) $(FPU_NO_CFLAGS) -c $< -o $@ |
/branches/dd/kernel/test/avltree/avltree1.c |
---|
48,8 → 48,7 |
static int test_tree_balance(avltree_node_t *node); |
static avltree_node_t *test_tree_parents(avltree_node_t *node); |
static void print_tree_structure_flat (avltree_node_t *node, int level) |
__attribute__ ((used)); |
static void print_tree_structure_flat (avltree_node_t *node, int level); |
static avltree_node_t *alloc_avltree_node(void); |
static avltree_node_t *test_tree_parents(avltree_node_t *node) |
62,15 → 61,14 |
if (node->lft) { |
tmp = test_tree_parents(node->lft); |
if (tmp != node) { |
printf("Bad parent pointer key: %" PRIu64 |
", address: %p\n", tmp->key, node->lft); |
printf("Bad parent pointer key: %d, address: %p\n", |
tmp->key, node->lft); |
} |
} |
if (node->rgt) { |
tmp = test_tree_parents(node->rgt); |
if (tmp != node) { |
printf("Bad parent pointer key: %" PRIu64 |
", address: %p\n", |
printf("Bad parent pointer key: %d, address: %p\n", |
tmp->key,node->rgt); |
} |
} |
96,8 → 94,7 |
* Prints the structure of the node, which is level levels from the top of the |
* tree. |
*/ |
static void |
print_tree_structure_flat(avltree_node_t *node, int level) |
static void print_tree_structure_flat(avltree_node_t *node, int level) |
{ |
/* |
* You can set the maximum level as high as you like. |
112,7 → 109,7 |
if (node == NULL) |
return; |
printf("%" PRIu64 "[%" PRIu8 "]", node->key, node->balance); |
printf("%d[%d]", node->key, node->balance); |
if (node->lft != NULL || node->rgt != NULL) { |
printf("("); |
133,7 → 130,6 |
for (i = 0; i < NODE_COUNT - 1; i++) { |
avltree_nodes[i].par = &avltree_nodes[i + 1]; |
} |
avltree_nodes[i].par = NULL; |
/* |
* Node keys which will be used for insertion. Up to NODE_COUNT size of |
173,6 → 169,7 |
for (i = 21; i < NODE_COUNT; i++) |
avltree_nodes[i].key = i * 3; |
avltree_nodes[i].par = NULL; |
first_free_node = &avltree_nodes[0]; |
} |
194,7 → 191,7 |
avltree_create(tree); |
if (!quiet) |
printf("Inserting %" PRIc " nodes...", node_count); |
printf("Inserting %d nodes...", node_count); |
for (i = 0; i < node_count; i++) { |
newnode = alloc_avltree_node(); |
/branches/dd/kernel/test/avltree/avltree1.def |
---|
1,6 → 1,6 |
{ |
"avltree1", |
"Test AVL tree operations", |
"Test Avl tree operations", |
&test_avltree1, |
true |
}, |
/branches/dd/kernel/test/synch/rwlock5.c |
---|
108,7 → 108,7 |
waitq_wakeup(&can_start, WAKEUP_ALL); |
while ((items_read.count != readers) || (items_written.count != writers)) { |
printf("%d readers remaining, %d writers remaining, readers_in=%d\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in); |
printf("%zd readers remaining, %zd writers remaining, readers_in=%zd\n", readers - items_read.count, writers - items_written.count, rwlock.readers_in); |
thread_usleep(100000); |
} |
} |
/branches/dd/kernel/test/synch/rwlock3.c |
---|
45,14 → 45,14 |
thread_detach(THREAD); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for reading....\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu: trying to lock rwlock for reading....\n", CPU->id, THREAD->tid); |
rwlock_read_lock(&rwlock); |
rwlock_read_unlock(&rwlock); |
if (!sh_quiet) { |
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid); |
printf("cpu%u, tid %" PRIu64 ": trying to lock rwlock for writing....\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu: success\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu: trying to lock rwlock for writing....\n", CPU->id, THREAD->tid); |
} |
rwlock_write_lock(&rwlock); |
59,7 → 59,7 |
rwlock_write_unlock(&rwlock); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 ": success\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu: success\n", CPU->id, THREAD->tid); |
atomic_dec(&thread_count); |
} |
88,7 → 88,7 |
while (atomic_get(&thread_count) > 0) { |
if (!quiet) |
printf("Threads left: %ld\n", atomic_get(&thread_count)); |
printf("Threads left: %d\n", atomic_get(&thread_count)); |
thread_sleep(1); |
} |
/branches/dd/kernel/test/synch/rwlock4.c |
---|
60,7 → 60,7 |
spinlock_lock(&rw_lock); |
rc = seed % max; |
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc; |
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc; |
spinlock_unlock(&rw_lock); |
return rc; |
} |
74,18 → 74,18 |
to = random(40000); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " w+ (%d)\n", CPU->id, THREAD->tid, to); |
printf("cpu%d, tid %llu w+ (%d)\n", CPU->id, THREAD->tid, to); |
rc = rwlock_write_lock_timeout(&rwlock, to); |
if (SYNCH_FAILED(rc)) { |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " w!\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu w!\n", CPU->id, THREAD->tid); |
atomic_dec(&thread_count); |
return; |
} |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " w=\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu w=\n", CPU->id, THREAD->tid); |
if (rwlock.readers_in) { |
if (!sh_quiet) |
106,7 → 106,7 |
rwlock_write_unlock(&rwlock); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " w-\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu w-\n", CPU->id, THREAD->tid); |
atomic_dec(&thread_count); |
} |
119,24 → 119,24 |
to = random(2000); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " r+ (%d)\n", CPU->id, THREAD->tid, to); |
printf("cpu%d, tid %llu r+ (%d)\n", CPU->id, THREAD->tid, to); |
rc = rwlock_read_lock_timeout(&rwlock, to); |
if (SYNCH_FAILED(rc)) { |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " r!\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu r!\n", CPU->id, THREAD->tid); |
atomic_dec(&thread_count); |
return; |
} |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " r=\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu r=\n", CPU->id, THREAD->tid); |
thread_usleep(30000); |
rwlock_read_unlock(&rwlock); |
if (!sh_quiet) |
printf("cpu%u, tid %" PRIu64 " r-\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu r-\n", CPU->id, THREAD->tid); |
atomic_dec(&thread_count); |
} |
159,8 → 159,8 |
context_save(&ctx); |
if (!quiet) { |
printf("sp=%#x, readers_in=%" PRIc "\n", ctx.sp, rwlock.readers_in); |
printf("Creating %" PRIu32 " readers\n", rd); |
printf("sp=%#x, readers_in=%d\n", ctx.sp, rwlock.readers_in); |
printf("Creating %d readers\n", rd); |
} |
for (i = 0; i < rd; i++) { |
168,11 → 168,11 |
if (thrd) |
thread_ready(thrd); |
else if (!quiet) |
printf("Could not create reader %" PRIu32 "\n", i); |
printf("Could not create reader %d\n", i); |
} |
if (!quiet) |
printf("Creating %" PRIu32 " writers\n", wr); |
printf("Creating %d writers\n", wr); |
for (i = 0; i < wr; i++) { |
thrd = thread_create(writer, NULL, TASK, 0, "writer", false); |
179,7 → 179,7 |
if (thrd) |
thread_ready(thrd); |
else if (!quiet) |
printf("Could not create writer %" PRIu32 "\n", i); |
printf("Could not create writer %d\n", i); |
} |
thread_usleep(20000); |
187,7 → 187,7 |
while (atomic_get(&thread_count) > 0) { |
if (!quiet) |
printf("Threads left: %ld\n", atomic_get(&thread_count)); |
printf("Threads left: %d\n", atomic_get(&thread_count)); |
thread_sleep(1); |
} |
/branches/dd/kernel/test/synch/semaphore2.c |
---|
53,7 → 53,7 |
spinlock_lock(&sem_lock); |
rc = seed % max; |
seed = (((seed << 2) ^ (seed >> 2)) * 487) + rc; |
seed = (((seed<<2) ^ (seed>>2)) * 487) + rc; |
spinlock_unlock(&sem_lock); |
return rc; |
} |
67,18 → 67,18 |
waitq_sleep(&can_start); |
to = random(20000); |
printf("cpu%u, tid %" PRIu64 " down+ (%d)\n", CPU->id, THREAD->tid, to); |
printf("cpu%d, tid %llu down+ (%d)\n", CPU->id, THREAD->tid, to); |
rc = semaphore_down_timeout(&sem, to); |
if (SYNCH_FAILED(rc)) { |
printf("cpu%u, tid %" PRIu64 " down!\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu down!\n", CPU->id, THREAD->tid); |
return; |
} |
printf("cpu%u, tid %" PRIu64 " down=\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu down=\n", CPU->id, THREAD->tid); |
thread_usleep(random(30000)); |
semaphore_up(&sem); |
printf("cpu%u, tid %" PRIu64 " up\n", CPU->id, THREAD->tid); |
printf("cpu%d, tid %llu up\n", CPU->id, THREAD->tid); |
} |
char * test_semaphore2(bool quiet) |
91,7 → 91,7 |
thread_t *thrd; |
k = random(7) + 1; |
printf("Creating %" PRIu32 " consumers\n", k); |
printf("Creating %d consumers\n", k); |
for (i = 0; i < k; i++) { |
thrd = thread_create(consumer, NULL, TASK, 0, "consumer", false); |
if (thrd) |
/branches/dd/kernel/test/thread/thread1.c |
---|
48,7 → 48,7 |
while (atomic_get(&finish)) { |
if (!sh_quiet) |
printf("%" PRIu64 " ", THREAD->tid); |
printf("%llu ", THREAD->tid); |
thread_usleep(100000); |
} |
atomic_inc(&threads_finished); |
/branches/dd/kernel/test/mm/purge1_skip.c |
---|
File deleted |
/branches/dd/kernel/test/mm/falloc2.c |
---|
55,10 → 55,10 |
uint8_t val = THREAD->tid % THREADS; |
index_t k; |
void **frames = (void **) malloc(MAX_FRAMES * sizeof(void *), FRAME_ATOMIC); |
uintptr_t * frames = (uintptr_t *) malloc(MAX_FRAMES * sizeof(uintptr_t), FRAME_ATOMIC); |
if (frames == NULL) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Unable to allocate frames\n", THREAD->tid, CPU->id); |
printf("Thread #%llu (cpu%d): Unable to allocate frames\n", THREAD->tid, CPU->id); |
atomic_inc(&thread_fail); |
atomic_dec(&thread_count); |
return; |
69,11 → 69,11 |
for (run = 0; run < THREAD_RUNS; run++) { |
for (order = 0; order <= MAX_ORDER; order++) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order); |
printf("Thread #%llu (cpu%d): Allocating %d frames blocks ... \n", THREAD->tid, CPU->id, 1 << order); |
allocated = 0; |
for (i = 0; i < (MAX_FRAMES >> order); i++) { |
frames[allocated] = frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
frames[allocated] = (uintptr_t)frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
if (frames[allocated]) { |
memsetb(frames[allocated], FRAME_SIZE << order, val); |
allocated++; |
82,16 → 82,16 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated); |
printf("Thread #%llu (cpu%d): %d blocks allocated.\n", THREAD->tid, CPU->id, allocated); |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Deallocating ... \n", THREAD->tid, CPU->id); |
printf("Thread #%llu (cpu%d): Deallocating ... \n", THREAD->tid, CPU->id); |
for (i = 0; i < allocated; i++) { |
for (k = 0; k <= (((index_t) FRAME_SIZE << order) - 1); k++) { |
if (((uint8_t *) frames[i])[k] != val) { |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Unexpected data (%c) in block %p offset %#" PRIi "\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k); |
printf("Thread #%llu (cpu%d): Unexpected data (%d) in block %p offset %#zx\n", THREAD->tid, CPU->id, ((char *) frames[i])[k], frames[i], k); |
atomic_inc(&thread_fail); |
goto cleanup; |
} |
100,7 → 100,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Finished run.\n", THREAD->tid, CPU->id); |
printf("Thread #%llu (cpu%d): Finished run.\n", THREAD->tid, CPU->id); |
} |
} |
108,7 → 108,7 |
free(frames); |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " (cpu%u): Exiting\n", THREAD->tid, CPU->id); |
printf("Thread #%llu (cpu%d): Exiting\n", THREAD->tid, CPU->id); |
atomic_dec(&thread_count); |
} |
124,7 → 124,7 |
thread_t * thrd = thread_create(falloc, NULL, TASK, 0, "falloc", false); |
if (!thrd) { |
if (!quiet) |
printf("Could not create thread %u\n", i); |
printf("Could not create thread %d\n", i); |
break; |
} |
thread_ready(thrd); |
132,7 → 132,7 |
while (atomic_get(&thread_count) > 0) { |
if (!quiet) |
printf("Threads left: %ld\n", atomic_get(&thread_count)); |
printf("Threads left: %d\n", atomic_get(&thread_count)); |
thread_sleep(1); |
} |
/branches/dd/kernel/test/mm/slab1.c |
---|
53,7 → 53,7 |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb(data[i], size, 0); |
memsetb((uintptr_t) data[i], size, 0); |
} |
if (!quiet) { |
71,7 → 71,7 |
for (i = 0; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb(data[i], size, 0); |
memsetb((uintptr_t) data[i], size, 0); |
} |
if (!quiet) { |
89,7 → 89,7 |
for (i = count / 2; i < count; i++) { |
data[i] = slab_alloc(cache, 0); |
memsetb(data[i], size, 0); |
memsetb((uintptr_t) data[i], size, 0); |
} |
if (!quiet) { |
137,7 → 137,7 |
thread_detach(THREAD); |
if (!sh_quiet) |
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
printf("Starting thread #%llu...\n", THREAD->tid); |
for (j = 0; j < 10; j++) { |
for (i = 0; i < THR_MEM_COUNT; i++) |
151,7 → 151,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " finished\n", THREAD->tid); |
printf("Thread #%llu finished\n", THREAD->tid); |
semaphore_up(&thr_sem); |
} |
/branches/dd/kernel/test/mm/slab2.c |
---|
68,8 → 68,8 |
slab_free(cache2, data2); |
break; |
} |
memsetb(data1, ITEM_SIZE, 0); |
memsetb(data2, ITEM_SIZE, 0); |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
memsetb((uintptr_t) data2, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
*((void **) data2) = olddata2; |
olddata1 = data1; |
100,7 → 100,7 |
printf("Incorrect memory size - use another test."); |
return; |
} |
memsetb(data1, ITEM_SIZE, 0); |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
olddata1 = data1; |
} |
108,7 → 108,7 |
data1 = slab_alloc(cache1, FRAME_ATOMIC); |
if (!data1) |
break; |
memsetb(data1, ITEM_SIZE, 0); |
memsetb((uintptr_t) data1, ITEM_SIZE, 0); |
*((void **) data1) = olddata1; |
olddata1 = data1; |
} |
150,11 → 150,11 |
mutex_unlock(&starter_mutex); |
if (!sh_quiet) |
printf("Starting thread #%" PRIu64 "...\n", THREAD->tid); |
printf("Starting thread #%llu...\n",THREAD->tid); |
/* Alloc all */ |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
printf("Thread #%llu allocating...\n", THREAD->tid); |
while (1) { |
/* Call with atomic to detect end of memory */ |
166,7 → 166,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
printf("Thread #%llu releasing...\n", THREAD->tid); |
while (data) { |
new = *((void **)data); |
176,7 → 176,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " allocating...\n", THREAD->tid); |
printf("Thread #%llu allocating...\n", THREAD->tid); |
while (1) { |
/* Call with atomic to detect end of memory */ |
188,7 → 188,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " releasing...\n", THREAD->tid); |
printf("Thread #%llu releasing...\n", THREAD->tid); |
while (data) { |
new = *((void **)data); |
198,7 → 198,7 |
} |
if (!sh_quiet) |
printf("Thread #%" PRIu64 " finished\n", THREAD->tid); |
printf("Thread #%llu finished\n", THREAD->tid); |
slab_print_list(); |
semaphore_up(&thr_sem); |
216,7 → 216,7 |
printf("Running stress test with size %d\n", size); |
condvar_initialize(&thread_starter); |
mutex_initialize(&starter_mutex, MUTEX_PASSIVE); |
mutex_initialize(&starter_mutex); |
thr_cache = slab_cache_create("thread_cache", size, 0, NULL, NULL, 0); |
semaphore_initialize(&thr_sem,0); |
/branches/dd/kernel/test/mm/purge1.c |
---|
26,6 → 26,8 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifdef ia64 |
#include <print.h> |
#include <test.h> |
#include <mm/page.h> |
45,10 → 47,10 |
tlb_entry_t entryd; |
int i; |
entryd.word[0] = 0; |
entryd.word[1] = 0; |
entryd.p = true; /* present */ |
entryd.ma = MA_WRITEBACK; |
entryd.a = true; /* already accessed */ |
75,9 → 77,11 |
dtc_mapping_insert(0 + i * (1 << PAGE_WIDTH), 9, entryd); |
} |
tlb_invalidate_pages(8, 0x0c000, 14); |
tlb_invalidate_pages(8,0x0c000,14); |
/* tlb_invalidate_all(); */ |
/*tlb_invalidate_all();*/ |
return NULL; |
} |
#endif |
/branches/dd/kernel/test/mm/purge1.def |
---|
1,3 → 1,4 |
#ifdef ia64 |
{ |
"purge1", |
"Itanium TLB purge test", |
4,3 → 5,4 |
&test_purge1, |
true |
}, |
#endif |
/branches/dd/kernel/test/fpu/mips2_skip.c |
---|
File deleted |
/branches/dd/kernel/test/fpu/fpu1_ia64.c |
---|
File deleted |
/branches/dd/kernel/test/fpu/fpu1_skip.c |
---|
File deleted |
/branches/dd/kernel/test/fpu/sse1_skip.c |
---|
File deleted |
/branches/dd/kernel/test/fpu/fpu1_x86.c |
---|
File deleted |
/branches/dd/kernel/test/fpu/mips2.c |
---|
26,6 → 26,8 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifdef mips32 |
#include <print.h> |
#include <debug.h> |
36,9 → 38,9 |
#include <arch.h> |
#define THREADS 50 |
#define DELAY 10000L |
#define ATTEMPTS 5 |
#define THREADS 50 |
#define DELAY 10000L |
#define ATTEMPTS 5 |
static atomic_t threads_ok; |
static atomic_t threads_fault; |
54,7 → 56,7 |
thread_detach(THREAD); |
waitq_sleep(&can_start); |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"mtc1 %0,$1" |
70,7 → 72,7 |
if (arg != after_arg) { |
if (!sh_quiet) |
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
printf("General reg tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
atomic_inc(&threads_fault); |
break; |
} |
87,13 → 89,13 |
thread_detach(THREAD); |
waitq_sleep(&can_start); |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"mtc1 %0,$1" |
: "=r" (arg) |
); |
scheduler(); |
asm volatile ( |
"mfc1 %0,$1" |
102,7 → 104,7 |
if (arg != after_arg) { |
if (!sh_quiet) |
printf("General reg tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
printf("General reg tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
atomic_inc(&threads_fault); |
break; |
} |
121,14 → 123,14 |
atomic_set(&threads_fault, 0); |
if (!quiet) |
printf("Creating %u threads... ", 2 * THREADS); |
printf("Creating %d threads... ", 2 * THREADS); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i); |
printf("could not create thread %d\n", 2 * i); |
break; |
} |
thread_ready(t); |
136,7 → 138,7 |
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i + 1); |
printf("could not create thread %d\n", 2 * i + 1); |
break; |
} |
thread_ready(t); |
160,3 → 162,5 |
return "Test failed"; |
} |
#endif |
/branches/dd/kernel/test/fpu/fpu1.c |
---|
0,0 → 1,230 |
/* |
* Copyright (c) 2005 Jakub Vana |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen)) |
#include <print.h> |
#include <debug.h> |
#include <test.h> |
#include <atomic.h> |
#include <proc/thread.h> |
#include <arch.h> |
#include <arch/arch.h> |
#define THREADS 150 |
#define ATTEMPTS 100 |
#define E_10e8 271828182 |
#define PI_10e8 314159265 |
#ifdef KERN_ia32_ARCH_H_ |
static inline double sqrt(double x) |
{ |
double v; |
asm ( |
"fsqrt\n" |
: "=t" (v) |
: "0" (x) |
); |
return v; |
} |
#endif |
#ifdef KERN_amd64_ARCH_H_ |
static inline double sqrt(double x) |
{ |
double v; |
asm ( |
"fsqrt\n" |
: "=t" (v) |
: "0" (x) |
); |
return v; |
} |
#endif |
#ifdef KERN_ia64_ARCH_H_ |
#undef PI_10e8 |
#define PI_10e8 3141592 |
static inline long double sqrt(long double a) |
{ |
long double x = 1; |
long double lx = 0; |
if (a < 0.00000000000000001) |
return 0; |
while(x != lx) { |
lx = x; |
x = (x + (a / x)) / 2; |
} |
return x; |
} |
#endif |
static atomic_t threads_ok; |
static atomic_t threads_fault; |
static waitq_t can_start; |
static bool sh_quiet; |
static void e(void *data) |
{ |
int i; |
double e, d, le, f; |
thread_detach(THREAD); |
waitq_sleep(&can_start); |
for (i = 0; i<ATTEMPTS; i++) { |
le = -1; |
e = 0; |
f = 1; |
for (d = 1; e != le; d *= f, f += 1) { |
le = e; |
e = e + 1 / d; |
} |
if ((int) (100000000 * e) != E_10e8) { |
if (!sh_quiet) |
printf("tid%llu: e*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * e), (unative_t) E_10e8); |
atomic_inc(&threads_fault); |
break; |
} |
} |
atomic_inc(&threads_ok); |
} |
static void pi(void *data) |
{ |
int i; |
double lpi, pi; |
double n, ab, ad; |
thread_detach(THREAD); |
waitq_sleep(&can_start); |
for (i = 0; i < ATTEMPTS; i++) { |
lpi = -1; |
pi = 0; |
for (n = 2, ab = sqrt(2); lpi != pi; n *= 2, ab = ad) { |
double sc, cd; |
sc = sqrt(1 - (ab * ab / 4)); |
cd = 1 - sc; |
ad = sqrt(ab * ab / 4 + cd * cd); |
lpi = pi; |
pi = 2 * n * ad; |
} |
#ifdef KERN_ia64_ARCH_H_ |
if ((int) (1000000 * pi) != PI_10e8) { |
if (!sh_quiet) |
printf("tid%llu: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (1000000 * pi), (unative_t) (PI_10e8 / 100)); |
atomic_inc(&threads_fault); |
break; |
} |
#else |
if ((int) (100000000 * pi) != PI_10e8) { |
if (!sh_quiet) |
printf("tid%llu: pi*10e8=%zd should be %zd\n", THREAD->tid, (unative_t) (100000000 * pi), (unative_t) PI_10e8); |
atomic_inc(&threads_fault); |
break; |
} |
#endif |
} |
atomic_inc(&threads_ok); |
} |
char * test_fpu1(bool quiet) |
{ |
unsigned int i, total = 0; |
sh_quiet = quiet; |
waitq_initialize(&can_start); |
atomic_set(&threads_ok, 0); |
atomic_set(&threads_fault, 0); |
if (!quiet) |
printf("Creating %d threads... ", 2 * THREADS); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
if (!(t = thread_create(e, NULL, TASK, 0, "e", false))) { |
if (!quiet) |
printf("could not create thread %d\n", 2 * i); |
break; |
} |
thread_ready(t); |
total++; |
if (!(t = thread_create(pi, NULL, TASK, 0, "pi", false))) { |
if (!quiet) |
printf("could not create thread %d\n", 2 * i + 1); |
break; |
} |
thread_ready(t); |
total++; |
} |
if (!quiet) |
printf("ok\n"); |
thread_sleep(1); |
waitq_wakeup(&can_start, WAKEUP_ALL); |
while (atomic_get(&threads_ok) != (long) total) { |
if (!quiet) |
printf("Threads left: %d\n", total - atomic_get(&threads_ok)); |
thread_sleep(1); |
} |
if (atomic_get(&threads_fault) == 0) |
return NULL; |
return "Test failed"; |
} |
#endif |
/branches/dd/kernel/test/fpu/sse1.c |
---|
26,6 → 26,8 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#if (defined(ia32) || defined(amd64) || defined(ia32xen)) |
#include <print.h> |
#include <debug.h> |
36,9 → 38,9 |
#include <arch.h> |
#define THREADS 25 |
#define DELAY 10000L |
#define ATTEMPTS 5 |
#define THREADS 25 |
#define DELAY 10000L |
#define ATTEMPTS 5 |
static atomic_t threads_ok; |
static atomic_t threads_fault; |
58,19 → 60,19 |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"movlpd %[arg], %%xmm2\n" |
: [arg] "=m" (arg) |
"movlpd %0, %%xmm2\n" |
: "=m" (arg) |
); |
delay(DELAY); |
asm volatile ( |
"movlpd %%xmm2, %[after_arg]\n" |
: [after_arg] "=m" (after_arg) |
"movlpd %%xmm2, %0\n" |
: "=m" (after_arg) |
); |
if (arg != after_arg) { |
if (!sh_quiet) |
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
printf("tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
atomic_inc(&threads_fault); |
break; |
} |
90,19 → 92,19 |
for (i = 0; i < ATTEMPTS; i++) { |
asm volatile ( |
"movlpd %[arg], %%xmm2\n" |
: [arg] "=m" (arg) |
"movlpd %0, %%xmm2\n" |
: "=m" (arg) |
); |
scheduler(); |
asm volatile ( |
"movlpd %%xmm2, %[after_arg]\n" |
: [after_arg] "=m" (after_arg) |
"movlpd %%xmm2, %0\n" |
: "=m" (after_arg) |
); |
if (arg != after_arg) { |
if (!sh_quiet) |
printf("tid%" PRIu64 ": arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
printf("tid%llu: arg(%d) != %d\n", THREAD->tid, arg, after_arg); |
atomic_inc(&threads_fault); |
break; |
} |
121,7 → 123,7 |
atomic_set(&threads_fault, 0); |
if (!quiet) |
printf("Creating %u threads... ", 2 * THREADS); |
printf("Creating %d threads... ", 2 * THREADS); |
for (i = 0; i < THREADS; i++) { |
thread_t *t; |
128,7 → 130,7 |
if (!(t = thread_create(testit1, (void *) ((unative_t) 2 * i), TASK, 0, "testit1", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i); |
printf("could not create thread %d\n", 2 * i); |
break; |
} |
thread_ready(t); |
136,7 → 138,7 |
if (!(t = thread_create(testit2, (void *) ((unative_t) 2 * i + 1), TASK, 0, "testit2", false))) { |
if (!quiet) |
printf("could not create thread %u\n", 2 * i + 1); |
printf("could not create thread %d\n", 2 * i + 1); |
break; |
} |
thread_ready(t); |
160,3 → 162,5 |
return "Test failed"; |
} |
#endif |
/branches/dd/kernel/test/fpu/mips2.def |
---|
1,3 → 1,4 |
#ifdef mips32 |
{ |
"mips2", |
"MIPS FPU test", |
4,3 → 5,4 |
&test_mips2, |
true |
}, |
#endif |
/branches/dd/kernel/test/fpu/fpu1.def |
---|
1,3 → 1,4 |
#if (defined(ia32) || defined(amd64) || defined(ia64) || defined(ia32xen)) |
{ |
"fpu1", |
"Intel FPU test", |
4,3 → 5,4 |
&test_fpu1, |
true |
}, |
#endif |
/branches/dd/kernel/test/fpu/sse1.def |
---|
1,3 → 1,4 |
#if (defined(ia32) || defined(amd64) || defined(ia32xen)) |
{ |
"sse1", |
"Intel SEE test", |
4,3 → 5,4 |
&test_sse1, |
true |
}, |
#endif |
/branches/dd/kernel/test/test.h |
---|
36,13 → 36,12 |
#define KERN_TEST_H_ |
#include <arch/types.h> |
#include <typedefs.h> |
typedef char *(*test_entry_t)(bool); |
typedef char * (* test_entry_t)(bool); |
typedef struct { |
char *name; |
char *desc; |
char * name; |
char * desc; |
test_entry_t entry; |
bool safe; |
} test_t; |
/branches/dd/kernel/test/print/print1.c |
---|
44,12 → 44,12 |
printf(" text 8.10s %8.10s \n", "text"); |
printf(" very long text 8.10s %8.10s \n", "very long text"); |
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n", 'a', 'b', 'c', 'd', 'e'); |
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", 1, 1, 1, 1, 1); |
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n", -1, -1, -1, -1, -1); |
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n", 17, 17, 17, 17, 17); |
printf(" char: c '%c', 3.2c '%3.2c', -3.2c '%-3.2c', 2.3c '%2.3c', -2.3c '%-2.3c' \n",'a', 'b', 'c', 'd', 'e' ); |
printf(" int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",1, 1, 1, 1, 1 ); |
printf(" -int: d '%d', 3.2d '%3.2d', -3.2d '%-3.2d', 2.3d '%2.3d', -2.3d '%-2.3d' \n",-1, -1, -1, -1, -1 ); |
printf(" 0xint: x '%#x', 5.3x '%#5.3x', -5.3x '%#-5.3x', 3.5x '%#3.5x', -3.5x '%#-3.5x' \n",17, 17, 17, 17, 17 ); |
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#" PRIxn "'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" ); |
printf("'%#llx' 64bit, '%#x' 32bit, '%#hhx' 8bit, '%#hx' 16bit, unative_t '%#zx'. '%#llx' 64bit and '%s' string.\n", 0x1234567887654321ll, 0x12345678, 0x12, 0x1234, nat, 0x1234567887654321ull, "Lovely string" ); |
printf(" Print to NULL '%s'\n", NULL); |
/branches/dd/kernel/test/debug/mips1_skip.c |
---|
File deleted |
/branches/dd/kernel/test/debug/mips1.c |
---|
25,6 → 25,8 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifdef mips32 |
#include <print.h> |
#include <debug.h> |
36,10 → 38,10 |
#include <arch.h> |
char *test_mips1(bool quiet) |
char * test_mips1(bool quiet) |
{ |
if (!quiet) |
printf("If kconsole is compiled in, you should enter debug mode now.\n"); |
printf("You should enter kconsole debug mode now.\n"); |
asm volatile ( |
"break\n" |
47,3 → 49,5 |
return "Back from debug mode"; |
} |
#endif |
/branches/dd/kernel/test/debug/mips1.def |
---|
1,3 → 1,4 |
#ifdef mips32 |
{ |
"mips1", |
"MIPS debug test", |
4,3 → 5,4 |
&test_mips1, |
false |
}, |
#endif |
/branches/dd/kernel/genarch/src/drivers/i8042/i8042.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/drivers/z8530/z8530.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/drivers/ega/ega.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/drivers/ns16550/ns16550.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/kbrd/kbrd.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/kbrd/scanc_pc.c |
---|
File deleted |
/branches/dd/kernel/genarch/src/kbrd/scanc_sun.c |
---|
File deleted |
/branches/dd/kernel/genarch/src/kbrd |
---|
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/multiboot/multiboot.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/srln/srln.c |
---|
File deleted |
/branches/dd/kernel/genarch/src/ofw/ebus.c |
---|
38,14 → 38,13 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/memstr.h> |
#include <arch/trap/interrupt.h> |
#include <string.h> |
#include <func.h> |
#include <panic.h> |
#include <debug.h> |
#include <macros.h> |
/** Apply EBUS ranges to EBUS register. */ |
bool |
ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) |
bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa) |
{ |
ofw_tree_property_t *prop; |
ofw_ebus_range_t *range; |
63,13 → 62,11 |
for (i = 0; i < ranges; i++) { |
if (reg->space != range[i].child_space) |
continue; |
if (overlaps(reg->addr, reg->size, range[i].child_base, |
range[i].size)) { |
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { |
ofw_pci_reg_t pci_reg; |
pci_reg.space = range[i].parent_space; |
pci_reg.addr = range[i].parent_base + |
(reg->addr - range[i].child_base); |
pci_reg.addr = range[i].parent_base + (reg->addr - range[i].child_base); |
pci_reg.size = reg->size; |
return ofw_pci_apply_ranges(node->parent, &pci_reg, pa); |
79,9 → 76,7 |
return false; |
} |
bool |
ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, |
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) |
bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr) |
{ |
ofw_tree_property_t *prop; |
ofw_tree_node_t *controller; |
109,8 → 104,8 |
unsigned int i; |
for (i = 0; i < count; i++) { |
if ((intr_map[i].space == space) && |
(intr_map[i].addr == addr) && (intr_map[i].intr == intr)) |
if ((intr_map[i].space == space) && (intr_map[i].addr == addr) |
&& (intr_map[i].intr == intr)) |
goto found; |
} |
return false; |
118,12 → 113,10 |
found: |
/* |
* We found the device that functions as an interrupt controller |
* for the interrupt. We also found partial mapping from interrupt to |
* INO. |
* for the interrupt. We also found partial mapping from interrupt to INO. |
*/ |
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), |
intr_map[i].controller_handle); |
controller = ofw_tree_find_node_by_handle(ofw_tree_lookup("/"), intr_map[i].controller_handle); |
if (!controller) |
return false; |
137,8 → 130,7 |
/* |
* Let the PCI do the next step in mapping the interrupt. |
*/ |
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, |
inr, cir, cir_arg)) |
if (!ofw_pci_map_interrupt(controller, NULL, intr_map[i].controller_ino, inr)) |
return false; |
return true; |
/branches/dd/kernel/genarch/src/ofw/fhc.c |
---|
38,7 → 38,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/drivers/fhc.h> |
#include <arch/memstr.h> |
#include <string.h> |
#include <func.h> |
#include <panic.h> |
#include <macros.h> |
67,7 → 67,7 |
return true; |
} |
if (strcmp(ofw_tree_node_name(node->parent), "central") != 0) |
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent)); |
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent)); |
ofw_central_reg_t central_reg; |
84,7 → 84,7 |
bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa) |
{ |
if (node->parent->parent) |
panic("Unexpected parent node: %s.", ofw_tree_node_name(node->parent)); |
panic("Unexpected parent node: %s.\n", ofw_tree_node_name(node->parent)); |
ofw_tree_property_t *prop; |
ofw_central_range_t *range; |
109,9 → 109,7 |
return false; |
} |
bool |
ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, |
uint32_t interrupt, int *inr, cir_t *cir, void **cir_arg) |
bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr) |
{ |
fhc_t *fhc = NULL; |
if (!node->device) { |
128,8 → 126,6 |
fhc_enable_interrupt(fhc, interrupt); |
*inr = interrupt; |
*cir = fhc_clear_interrupt; |
*cir_arg = fhc; |
return true; |
} |
/branches/dd/kernel/genarch/src/ofw/ofw_tree.c |
---|
38,7 → 38,7 |
#include <genarch/ofw/ofw_tree.h> |
#include <arch/memstr.h> |
#include <mm/slab.h> |
#include <string.h> |
#include <func.h> |
#include <print.h> |
#include <panic.h> |
54,14 → 54,12 |
/** Get OpenFirmware node property. |
* |
* @param node Node in which to lookup the property. |
* @param name Name of the property. |
* @param node Node in which to lookup the property. |
* @param name Name of the property. |
* |
* @return Pointer to the property structure or NULL if no such |
* property. |
* @return Pointer to the property structure or NULL if no such property. |
*/ |
ofw_tree_property_t * |
ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) |
ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name) |
{ |
unsigned int i; |
75,9 → 73,9 |
/** Return value of the 'name' property. |
* |
* @param node Node of interest. |
* @param node Node of interest. |
* |
* @return Value of the 'name' property belonging to the node. |
* @return Value of the 'name' property belonging to the node. |
*/ |
const char *ofw_tree_node_name(const ofw_tree_node_t *node) |
{ |
85,10 → 83,10 |
prop = ofw_tree_getprop(node, "name"); |
if (!prop) |
panic("Node without name property."); |
panic("Node without name property.\n"); |
if (prop->size < 2) |
panic("Invalid name property."); |
panic("Invalid name property.\n"); |
return prop->value; |
} |
95,11 → 93,10 |
/** Lookup child of given name. |
* |
* @param node Node whose child is being looked up. |
* @param name Name of the child being looked up. |
* @param node Node whose child is being looked up. |
* @param name Name of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
* @return NULL if there is no such child or pointer to the matching child node. |
*/ |
ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name) |
{ |
130,14 → 127,12 |
/** Lookup first child of given device type. |
* |
* @param node Node whose child is being looked up. |
* @param name Device type of the child being looked up. |
* @param node Node whose child is being looked up. |
* @param name Device type of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
* @return NULL if there is no such child or pointer to the matching child node. |
*/ |
ofw_tree_node_t * |
ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name) |
ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
158,14 → 153,12 |
* Child nodes are looked up recursively contrary to peer nodes that |
* are looked up iteratively to avoid stack overflow. |
* |
* @param root Root of the searched subtree. |
* @param handle OpenFirmware handle. |
* @param root Root of the searched subtree. |
* @param handle OpenFirmware handle. |
* |
* @return NULL if there is no such node or pointer to the matching |
* node. |
* @return NULL if there is no such node or pointer to the matching node. |
*/ |
ofw_tree_node_t * |
ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) |
ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle) |
{ |
ofw_tree_node_t *cur; |
187,14 → 180,12 |
/** Lookup first peer of given device type. |
* |
* @param node Node whose peer is being looked up. |
* @param name Device type of the child being looked up. |
* @param node Node whose peer is being looked up. |
* @param name Device type of the child being looked up. |
* |
* @return NULL if there is no such child or pointer to the |
* matching child node. |
* @return NULL if there is no such child or pointer to the matching child node. |
*/ |
ofw_tree_node_t * |
ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name) |
ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
211,41 → 202,15 |
} |
/** Lookup first peer of given name. |
* |
* @param node Node whose peer is being looked up. |
* @param name Name of the child being looked up. |
* |
* @return NULL if there is no such peer or pointer to the matching |
* peer node. |
*/ |
ofw_tree_node_t * |
ofw_tree_find_peer_by_name(ofw_tree_node_t *node, const char *name) |
{ |
ofw_tree_node_t *cur; |
ofw_tree_property_t *prop; |
for (cur = node->peer; cur; cur = cur->peer) { |
prop = ofw_tree_getprop(cur, "name"); |
if (!prop || !prop->value) |
continue; |
if (strcmp(prop->value, name) == 0) |
return cur; |
} |
return NULL; |
} |
/** Lookup OpenFirmware node by its path. |
* |
* @param path Path to the node. |
* @param path Path to the node. |
* |
* @return NULL if there is no such node or pointer to the leaf |
* node. |
* @return NULL if there is no such node or pointer to the leaf node. |
*/ |
ofw_tree_node_t *ofw_tree_lookup(const char *path) |
{ |
char buf[NAME_BUF_LEN + 1]; |
char buf[NAME_BUF_LEN+1]; |
ofw_tree_node_t *node = ofw_root; |
index_t i, j; |
271,8 → 236,8 |
* Child nodes are processed recursively and peer nodes are processed |
* iteratively in order to avoid stack overflow. |
* |
* @param node Root of the subtree. |
* @param path Current path, NULL for the very root of the entire tree. |
* @param node Root of the subtree. |
* @param path Current path, NULL for the very root of the entire tree. |
*/ |
static void ofw_tree_node_print(const ofw_tree_node_t *node, const char *path) |
{ |
/branches/dd/kernel/genarch/src/ofw/pci.c |
---|
39,7 → 39,7 |
#include <arch/drivers/pci.h> |
#include <arch/trap/interrupt.h> |
#include <arch/memstr.h> |
#include <string.h> |
#include <func.h> |
#include <panic.h> |
#include <macros.h> |
49,8 → 49,7 |
#define PCI_IGN 0x1f |
bool |
ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) |
bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa) |
{ |
ofw_tree_property_t *prop; |
ofw_pci_range_t *range; |
69,13 → 68,10 |
unsigned int i; |
for (i = 0; i < ranges; i++) { |
if ((reg->space & PCI_SPACE_MASK) != |
(range[i].space & PCI_SPACE_MASK)) |
if ((reg->space & PCI_SPACE_MASK) != (range[i].space & PCI_SPACE_MASK)) |
continue; |
if (overlaps(reg->addr, reg->size, range[i].child_base, |
range[i].size)) { |
*pa = range[i].parent_base + |
(reg->addr - range[i].child_base); |
if (overlaps(reg->addr, reg->size, range[i].child_base, range[i].size)) { |
*pa = range[i].parent_base + (reg->addr - range[i].child_base); |
return true; |
} |
} |
83,9 → 79,7 |
return false; |
} |
bool |
ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, |
ofw_pci_reg_t *out) |
bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out) |
{ |
if (reg->space & PCI_ABS_MASK) { |
/* already absolute */ |
101,7 → 95,7 |
prop = ofw_tree_getprop(node, "assigned-addresses"); |
if (!prop) |
panic("Cannot find 'assigned-addresses' property."); |
panic("Can't find \"assigned-addresses\" property.\n"); |
assigned_addresses = prop->size / sizeof(ofw_pci_reg_t); |
assigned_address = prop->value; |
109,8 → 103,7 |
unsigned int i; |
for (i = 0; i < assigned_addresses; i++) { |
if ((assigned_address[i].space & PCI_REG_MASK) == |
(reg->space & PCI_REG_MASK)) { |
if ((assigned_address[i].space & PCI_REG_MASK) == (reg->space & PCI_REG_MASK)) { |
out->space = assigned_address[i].space; |
out->addr = reg->addr + assigned_address[i].addr; |
out->size = reg->size; |
126,9 → 119,7 |
* So far, we only know how to map interrupts of non-PCI devices connected |
* to a PCI bridge. |
*/ |
bool |
ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, |
int *inr, cir_t *cir, void **cir_arg) |
bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr) |
{ |
pci_t *pci = node->device; |
if (!pci) { |
141,8 → 132,6 |
pci_enable_interrupt(pci, ino); |
*inr = (PCI_IGN << IGN_SHIFT) | ino; |
*cir = pci_clear_interrupt; |
*cir_arg = pci; |
return true; |
} |
/branches/dd/kernel/genarch/src/kbd/key.c |
---|
0,0 → 1,252 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Key processing. |
*/ |
#include <genarch/kbd/key.h> |
#include <genarch/kbd/scanc.h> |
#ifdef CONFIG_I8042 |
#include <genarch/kbd/scanc_pc.h> |
#endif |
#if (defined(CONFIG_Z8530) || defined(CONFIG_NS16550)) |
#include <genarch/kbd/scanc_sun.h> |
#endif |
#include <synch/spinlock.h> |
#include <console/chardev.h> |
#include <macros.h> |
#define PRESSED_SHIFT (1<<0) |
#define PRESSED_CAPSLOCK (1<<1) |
#define LOCKED_CAPSLOCK (1<<0) |
#define ACTIVE_READ_BUFF_SIZE 16 /* Must be power of 2 */ |
chardev_t kbrd; |
static uint8_t active_read_buff[ACTIVE_READ_BUFF_SIZE]; |
SPINLOCK_INITIALIZE(keylock); /**< keylock protects keyflags and lockflags. */ |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
/** Process release of key. |
* |
* @param sc Scancode of the key being released. |
*/ |
void key_released(uint8_t sc) |
{ |
spinlock_lock(&keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags &= ~PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags &= ~PRESSED_CAPSLOCK; |
if (lockflags & LOCKED_CAPSLOCK) |
lockflags &= ~LOCKED_CAPSLOCK; |
else |
lockflags |= LOCKED_CAPSLOCK; |
break; |
default: |
break; |
} |
spinlock_unlock(&keylock); |
} |
/** Process keypress. |
* |
* @param sc Scancode of the key being pressed. |
*/ |
void key_pressed(uint8_t sc) |
{ |
char *map = sc_primary_map; |
char ascii = sc_primary_map[sc]; |
bool shift, capslock; |
bool letter = false; |
spinlock_lock(&keylock); |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SPEC_ESCAPE: |
break; |
case SC_LEFTARR: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x5b); |
chardev_push_character(&kbrd, 0x44); |
break; |
case SC_RIGHTARR: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x5b); |
chardev_push_character(&kbrd, 0x43); |
break; |
case SC_UPARR: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x5b); |
chardev_push_character(&kbrd, 0x41); |
break; |
case SC_DOWNARR: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x5b); |
chardev_push_character(&kbrd, 0x42); |
break; |
case SC_HOME: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x4f); |
chardev_push_character(&kbrd, 0x48); |
break; |
case SC_END: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x4f); |
chardev_push_character(&kbrd, 0x46); |
break; |
case SC_DELETE: |
chardev_push_character(&kbrd, 0x1b); |
chardev_push_character(&kbrd, 0x5b); |
chardev_push_character(&kbrd, 0x33); |
chardev_push_character(&kbrd, 0x7e); |
break; |
default: |
letter = islower(ascii); |
capslock = (keyflags & PRESSED_CAPSLOCK) || |
(lockflags & LOCKED_CAPSLOCK); |
shift = keyflags & PRESSED_SHIFT; |
if (letter && capslock) |
shift = !shift; |
if (shift) |
map = sc_secondary_map; |
chardev_push_character(&kbrd, map[sc]); |
break; |
} |
spinlock_unlock(&keylock); |
} |
uint8_t active_read_buff_read(void) |
{ |
static int i=0; |
i &= (ACTIVE_READ_BUFF_SIZE-1); |
if(!active_read_buff[i]) { |
return 0; |
} |
return active_read_buff[i++]; |
} |
void active_read_buff_write(uint8_t ch) |
{ |
static int i=0; |
active_read_buff[i] = ch; |
i++; |
i &= (ACTIVE_READ_BUFF_SIZE-1); |
active_read_buff[i]=0; |
} |
void active_read_key_pressed(uint8_t sc) |
{ |
char *map = sc_primary_map; |
char ascii = sc_primary_map[sc]; |
bool shift, capslock; |
bool letter = false; |
/*spinlock_lock(&keylock);*/ |
switch (sc) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SPEC_ESCAPE: |
break; |
case SC_LEFTARR: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x5b); |
active_read_buff_write(0x44); |
break; |
case SC_RIGHTARR: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x5b); |
active_read_buff_write(0x43); |
break; |
case SC_UPARR: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x5b); |
active_read_buff_write(0x41); |
break; |
case SC_DOWNARR: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x5b); |
active_read_buff_write(0x42); |
break; |
case SC_HOME: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x4f); |
active_read_buff_write(0x48); |
break; |
case SC_END: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x4f); |
active_read_buff_write(0x46); |
break; |
case SC_DELETE: |
active_read_buff_write(0x1b); |
active_read_buff_write(0x5b); |
active_read_buff_write(0x33); |
active_read_buff_write(0x7e); |
break; |
default: |
letter = islower(ascii); |
capslock = (keyflags & PRESSED_CAPSLOCK) || |
(lockflags & LOCKED_CAPSLOCK); |
shift = keyflags & PRESSED_SHIFT; |
if (letter && capslock) |
shift = !shift; |
if (shift) |
map = sc_secondary_map; |
active_read_buff_write(map[sc]); |
break; |
} |
/*spinlock_unlock(&keylock);*/ |
} |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/kbd/i8042.c |
---|
0,0 → 1,240 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief i8042 processor driver. |
* |
* It takes care of low-level keyboard functions. |
*/ |
#include <genarch/kbd/i8042.h> |
#include <genarch/kbd/key.h> |
#include <genarch/kbd/scanc.h> |
#include <genarch/kbd/scanc_pc.h> |
#include <arch/drivers/i8042.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <ipc/irq.h> |
/* Keyboard commands. */ |
#define KBD_ENABLE 0xf4 |
#define KBD_DISABLE 0xf5 |
#define KBD_ACK 0xfa |
/* |
* 60 Write 8042 Command Byte: next data byte written to port 60h is |
* placed in 8042 command register. Format: |
* |
* |7|6|5|4|3|2|1|0|8042 Command Byte |
* | | | | | | | `---- 1=enable output register full interrupt |
* | | | | | | `----- should be 0 |
* | | | | | `------ 1=set status register system, 0=clear |
* | | | | `------- 1=override keyboard inhibit, 0=allow inhibit |
* | | | `-------- disable keyboard I/O by driving clock line low |
* | | `--------- disable auxiliary device, drives clock line low |
* | `---------- IBM scancode translation 0=AT, 1=PC/XT |
* `----------- reserved, should be 0 |
*/ |
#define i8042_SET_COMMAND 0x60 |
#define i8042_COMMAND 0x69 |
#define i8042_BUFFER_FULL_MASK 0x01 |
#define i8042_WAIT_MASK 0x02 |
#define i8042_MOUSE_DATA 0x20 |
static void i8042_suspend(chardev_t *); |
static void i8042_resume(chardev_t *); |
static chardev_operations_t ops = { |
.suspend = i8042_suspend, |
.resume = i8042_resume, |
.read = i8042_key_read |
}; |
/** Structure for i8042's IRQ. */ |
static irq_t i8042_kbd_irq; |
static irq_t i8042_mouse_irq; |
void i8042_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&i8042_kbd_irq.lock); |
i8042_kbd_irq.notif_cfg.notify = false; |
spinlock_unlock(&i8042_kbd_irq.lock); |
spinlock_lock(&i8042_mouse_irq.lock); |
i8042_mouse_irq.notif_cfg.notify = false; |
spinlock_unlock(&i8042_mouse_irq.lock); |
interrupts_restore(ipl); |
} |
void i8042_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&i8042_kbd_irq.lock); |
if (i8042_kbd_irq.notif_cfg.answerbox) |
i8042_kbd_irq.notif_cfg.notify = true; |
spinlock_unlock(&i8042_kbd_irq.lock); |
spinlock_lock(&i8042_mouse_irq.lock); |
if (i8042_mouse_irq.notif_cfg.answerbox) |
i8042_mouse_irq.notif_cfg.notify = true; |
spinlock_unlock(&i8042_mouse_irq.lock); |
interrupts_restore(ipl); |
} |
static irq_ownership_t i8042_claim(void) |
{ |
return IRQ_ACCEPT; |
} |
static void i8042_irq_handler(irq_t *irq, void *arg, ...) |
{ |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else { |
uint8_t data; |
uint8_t status; |
while (((status = i8042_status_read()) & i8042_BUFFER_FULL_MASK)) { |
data = i8042_data_read(); |
if ((status & i8042_MOUSE_DATA)) |
continue; |
if (data & KEY_RELEASE) |
key_released(data ^ KEY_RELEASE); |
else |
key_pressed(data); |
} |
} |
} |
/** Initialize i8042. */ |
void i8042_init(devno_t kbd_devno, inr_t kbd_inr, devno_t mouse_devno, inr_t mouse_inr) |
{ |
chardev_initialize("i8042_kbd", &kbrd, &ops); |
stdin = &kbrd; |
irq_initialize(&i8042_kbd_irq); |
i8042_kbd_irq.devno = kbd_devno; |
i8042_kbd_irq.inr = kbd_inr; |
i8042_kbd_irq.claim = i8042_claim; |
i8042_kbd_irq.handler = i8042_irq_handler; |
irq_register(&i8042_kbd_irq); |
irq_initialize(&i8042_mouse_irq); |
i8042_mouse_irq.devno = mouse_devno; |
i8042_mouse_irq.inr = mouse_inr; |
i8042_mouse_irq.claim = i8042_claim; |
i8042_mouse_irq.handler = i8042_irq_handler; |
irq_register(&i8042_mouse_irq); |
#ifndef ia64 |
trap_virtual_enable_irqs(1 << kbd_inr); |
trap_virtual_enable_irqs(1 << mouse_inr); |
#endif |
/* |
* Clear input buffer. |
* Number of iterations is limited to prevent infinite looping. |
*/ |
int i; |
for (i = 0; (i8042_status_read() & i8042_BUFFER_FULL_MASK) && i < 100; i++) { |
i8042_data_read(); |
} |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.devno", NULL, kbd_devno); |
sysinfo_set_item_val("kbd.inr", NULL, kbd_inr); |
sysinfo_set_item_val("mouse", NULL, true); |
sysinfo_set_item_val("mouse.devno", NULL, mouse_devno); |
sysinfo_set_item_val("mouse.inr", NULL, mouse_inr); |
i8042_grab(); |
} |
/* Called from getc(). */ |
void i8042_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
void i8042_suspend(chardev_t *d) |
{ |
} |
char i8042_key_read(chardev_t *d) |
{ |
char ch; |
while(!(ch = active_read_buff_read())) { |
uint8_t x; |
while (!(i8042_status_read() & i8042_BUFFER_FULL_MASK)) |
; |
x = i8042_data_read(); |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
active_read_key_pressed(x); |
} |
return ch; |
} |
/** Poll for key press and release events. |
* |
* This function can be used to implement keyboard polling. |
*/ |
void i8042_poll(void) |
{ |
uint8_t x; |
while (((x = i8042_status_read() & i8042_BUFFER_FULL_MASK))) { |
x = i8042_data_read(); |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
key_pressed(x); |
} |
} |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/kbd/ns16550.c |
---|
0,0 → 1,224 |
/* |
* Copyright (c) 2001-2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief NS 16550 serial port / keyboard driver. |
*/ |
#include <genarch/kbd/ns16550.h> |
#include <genarch/kbd/key.h> |
#include <genarch/kbd/scanc.h> |
#include <genarch/kbd/scanc_sun.h> |
#include <arch/drivers/kbd.h> |
#include <arch/drivers/ns16550.h> |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <interrupt.h> |
#include <arch/interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <synch/spinlock.h> |
#define LSR_DATA_READY 0x01 |
/** Structure representing the ns16550. */ |
static ns16550_t ns16550; |
/** Structure for ns16550's IRQ. */ |
static irq_t ns16550_irq; |
/* |
* These codes read from ns16550 data register are silently ignored. |
*/ |
#define IGNORE_CODE 0x7f /* all keys up */ |
static void ns16550_suspend(chardev_t *); |
static void ns16550_resume(chardev_t *); |
static chardev_operations_t ops = { |
.suspend = ns16550_suspend, |
.resume = ns16550_resume, |
.read = ns16550_key_read |
}; |
void ns16550_interrupt(void); |
/** Initialize keyboard and service interrupts using kernel routine */ |
void ns16550_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
ns16550_ier_write(&ns16550, IER_ERBFI); /* enable receiver interrupt */ |
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) |
(void) ns16550_rbr_read(&ns16550); |
spinlock_lock(&ns16550_irq.lock); |
ns16550_irq.notif_cfg.notify = false; |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
} |
/** Resume the former interrupt vector */ |
void ns16550_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&ns16550_irq.lock); |
if (ns16550_irq.notif_cfg.answerbox) |
ns16550_irq.notif_cfg.notify = true; |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initialize ns16550. |
* |
* @param devno Device number. |
* @param inr Interrupt number. |
* @param vaddr Virtual address of device's registers. |
*/ |
void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr) |
{ |
chardev_initialize("ns16550_kbd", &kbrd, &ops); |
stdin = &kbrd; |
ns16550.devno = devno; |
ns16550.reg = (uint8_t *) vaddr; |
irq_initialize(&ns16550_irq); |
ns16550_irq.devno = devno; |
ns16550_irq.inr = inr; |
ns16550_irq.claim = ns16550_claim; |
ns16550_irq.handler = ns16550_irq_handler; |
irq_register(&ns16550_irq); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_NS16550); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr); |
ns16550_grab(); |
} |
/** Process ns16550 interrupt. */ |
void ns16550_interrupt(void) |
{ |
/* TODO |
* |
* ns16550 works in the polled mode so far. |
*/ |
} |
/* Called from getc(). */ |
void ns16550_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
void ns16550_suspend(chardev_t *d) |
{ |
} |
char ns16550_key_read(chardev_t *d) |
{ |
char ch; |
while(!(ch = active_read_buff_read())) { |
uint8_t x; |
while (!(ns16550_lsr_read(&ns16550) & LSR_DATA_READY)) |
; |
x = ns16550_rbr_read(&ns16550); |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
active_read_key_pressed(x); |
} |
} |
return ch; |
} |
/** Poll for key press and release events. |
* |
* This function can be used to implement keyboard polling. |
*/ |
void ns16550_poll(void) |
{ |
ipl_t ipl; |
ipl = interrupts_disable(); |
spinlock_lock(&ns16550_irq.lock); |
if (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
if (ns16550_irq.notif_cfg.notify && ns16550_irq.notif_cfg.answerbox) { |
/* |
* Send IPC notification. |
*/ |
ipc_irq_send_notif(&ns16550_irq); |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
return; |
} |
} |
spinlock_unlock(&ns16550_irq.lock); |
interrupts_restore(ipl); |
while (ns16550_lsr_read(&ns16550) & LSR_DATA_READY) { |
uint8_t x; |
x = ns16550_rbr_read(&ns16550); |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
key_pressed(x); |
} |
} |
} |
irq_ownership_t ns16550_claim(void) |
{ |
return (ns16550_lsr_read(&ns16550) & LSR_DATA_READY); |
} |
void ns16550_irq_handler(irq_t *irq, void *arg, ...) |
{ |
panic("Not yet implemented, ns16550 works in polled mode.\n"); |
} |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/kbd/z8530.c |
---|
0,0 → 1,215 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Zilog 8530 serial port / keyboard driver. |
*/ |
#include <genarch/kbd/z8530.h> |
#include <genarch/kbd/key.h> |
#include <genarch/kbd/scanc.h> |
#include <genarch/kbd/scanc_sun.h> |
#include <arch/drivers/z8530.h> |
#include <ddi/irq.h> |
#include <ipc/irq.h> |
#include <arch/interrupt.h> |
#include <arch/drivers/kbd.h> |
#include <arch/drivers/fhc.h> |
#include <cpu.h> |
#include <arch/asm.h> |
#include <arch.h> |
#include <console/chardev.h> |
#include <console/console.h> |
#include <interrupt.h> |
#include <sysinfo/sysinfo.h> |
#include <print.h> |
/* |
* These codes read from z8530 data register are silently ignored. |
*/ |
#define IGNORE_CODE 0x7f /* all keys up */ |
static z8530_t z8530; /**< z8530 device structure. */ |
static irq_t z8530_irq; /**< z8530's IRQ. */ |
static void z8530_suspend(chardev_t *); |
static void z8530_resume(chardev_t *); |
static chardev_operations_t ops = { |
.suspend = z8530_suspend, |
.resume = z8530_resume, |
.read = z8530_key_read |
}; |
/** Initialize keyboard and service interrupts using kernel routine. */ |
void z8530_grab(void) |
{ |
ipl_t ipl = interrupts_disable(); |
(void) z8530_read_a(&z8530, RR8); |
/* |
* Clear any pending TX interrupts or we never manage |
* to set FHC UART interrupt state to idle. |
*/ |
z8530_write_a(&z8530, WR0, WR0_TX_IP_RST); |
z8530_write_a(&z8530, WR1, WR1_IARCSC); /* interrupt on all characters */ |
/* 8 bits per character and enable receiver */ |
z8530_write_a(&z8530, WR3, WR3_RX8BITSCH | WR3_RX_ENABLE); |
z8530_write_a(&z8530, WR9, WR9_MIE); /* Master Interrupt Enable. */ |
spinlock_lock(&z8530_irq.lock); |
z8530_irq.notif_cfg.notify = false; |
spinlock_unlock(&z8530_irq.lock); |
interrupts_restore(ipl); |
} |
/** Resume the former IPC notification behavior. */ |
void z8530_release(void) |
{ |
ipl_t ipl = interrupts_disable(); |
spinlock_lock(&z8530_irq.lock); |
if (z8530_irq.notif_cfg.answerbox) |
z8530_irq.notif_cfg.notify = true; |
spinlock_unlock(&z8530_irq.lock); |
interrupts_restore(ipl); |
} |
/** Initialize z8530. */ |
void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr) |
{ |
chardev_initialize("z8530_kbd", &kbrd, &ops); |
stdin = &kbrd; |
z8530.devno = devno; |
z8530.reg = (uint8_t *) vaddr; |
irq_initialize(&z8530_irq); |
z8530_irq.devno = devno; |
z8530_irq.inr = inr; |
z8530_irq.claim = z8530_claim; |
z8530_irq.handler = z8530_irq_handler; |
irq_register(&z8530_irq); |
sysinfo_set_item_val("kbd", NULL, true); |
sysinfo_set_item_val("kbd.type", NULL, KBD_Z8530); |
sysinfo_set_item_val("kbd.devno", NULL, devno); |
sysinfo_set_item_val("kbd.inr", NULL, inr); |
sysinfo_set_item_val("kbd.address.virtual", NULL, vaddr); |
z8530_grab(); |
} |
/** Process z8530 interrupt. |
* |
* @param n Interrupt vector. |
* @param istate Interrupted state. |
*/ |
void z8530_interrupt(void) |
{ |
z8530_poll(); |
} |
/* Called from getc(). */ |
void z8530_resume(chardev_t *d) |
{ |
} |
/* Called from getc(). */ |
void z8530_suspend(chardev_t *d) |
{ |
} |
char z8530_key_read(chardev_t *d) |
{ |
char ch; |
while(!(ch = active_read_buff_read())) { |
uint8_t x; |
while (!(z8530_read_a(&z8530, RR0) & RR0_RCA)) |
; |
x = z8530_read_a(&z8530, RR8); |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
active_read_key_pressed(x); |
} |
} |
return ch; |
} |
/** Poll for key press and release events. |
* |
* This function can be used to implement keyboard polling. |
*/ |
void z8530_poll(void) |
{ |
uint8_t x; |
while (z8530_read_a(&z8530, RR0) & RR0_RCA) { |
x = z8530_read_a(&z8530, RR8); |
if (x != IGNORE_CODE) { |
if (x & KEY_RELEASE) |
key_released(x ^ KEY_RELEASE); |
else |
key_pressed(x); |
} |
} |
} |
irq_ownership_t z8530_claim(void) |
{ |
return (z8530_read_a(&z8530, RR0) & RR0_RCA); |
} |
void z8530_irq_handler(irq_t *irq, void *arg, ...) |
{ |
/* |
* So far, we know we got this interrupt through the FHC. |
* Since we don't have enough documentation about the FHC |
* and because the interrupt looks like level sensitive, |
* we cannot handle it by scheduling one of the level |
* interrupt traps. Process the interrupt directly. |
*/ |
if (irq->notif_cfg.notify && irq->notif_cfg.answerbox) |
ipc_irq_send_notif(irq); |
else |
z8530_interrupt(); |
fhc_clear_interrupt(central_fhc, irq->inr); |
} |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/kbd/scanc_pc.c |
---|
0,0 → 1,200 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for pc keyboards. |
*/ |
#include <genarch/kbd/scanc.h> |
/** Primary meaning of scancodes. */ |
char sc_primary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - Esc */ |
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', |
'\b', /* 0x0e - Backspace */ |
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', |
'`', |
SPECIAL, /* 0x2a - LShift */ |
'\\', |
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
SPECIAL, /* 0x3b - F1 */ |
SPECIAL, /* 0x3c - F2 */ |
SPECIAL, /* 0x3d - F3 */ |
SPECIAL, /* 0x3e - F4 */ |
SPECIAL, /* 0x3f - F5 */ |
SPECIAL, /* 0x40 - F6 */ |
SPECIAL, /* 0x41 - F7 */ |
SPECIAL, /* 0x42 - F8 */ |
SPECIAL, /* 0x43 - F9 */ |
SPECIAL, /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
SPECIAL, /* 0x57 - F11 */ |
SPECIAL, /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** Secondary meaning of scancodes. */ |
char sc_secondary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - Esc */ |
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', |
SPECIAL, /* 0x0e - Backspace */ |
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', |
'~', |
SPECIAL, /* 0x2a - LShift */ |
'|', |
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
SPECIAL, /* 0x3b - F1 */ |
SPECIAL, /* 0x3c - F2 */ |
SPECIAL, /* 0x3d - F3 */ |
SPECIAL, /* 0x3e - F4 */ |
SPECIAL, /* 0x3f - F5 */ |
SPECIAL, /* 0x40 - F6 */ |
SPECIAL, /* 0x41 - F7 */ |
SPECIAL, /* 0x42 - F8 */ |
SPECIAL, /* 0x43 - F9 */ |
SPECIAL, /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
SPECIAL, /* 0x57 - F11 */ |
SPECIAL, /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/kbd/scanc_sun.c |
---|
0,0 → 1,304 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for Sun keyboards. |
*/ |
#include <genarch/kbd/scanc.h> |
/** Primary meaning of scancodes. */ |
char sc_primary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = SPECIAL, /* F1 */ |
[0x06] = SPECIAL, /* F2 */ |
[0x07] = SPECIAL, /* F10 */ |
[0x08] = SPECIAL, /* F3 */ |
[0x09] = SPECIAL, /* F11 */ |
[0x0a] = SPECIAL, /* F4 */ |
[0x0b] = SPECIAL, /* F12 */ |
[0x0c] = SPECIAL, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = SPECIAL, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = SPECIAL, /* F7 */ |
[0x11] = SPECIAL, /* F8 */ |
[0x12] = SPECIAL, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* Esc */ |
[0x1e] = '1', |
[0x1f] = '2', |
[0x20] = '3', |
[0x21] = '4', |
[0x22] = '5', |
[0x23] = '6', |
[0x24] = '7', |
[0x25] = '8', |
[0x26] = '9', |
[0x27] = '0', |
[0x28] = '-', |
[0x29] = '=', |
[0x2a] = '`', |
[0x2b] = '\b', /* Backspace */ |
[0x2c] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* Home */ |
[0x35] = '\t', /* Tab */ |
[0x36] = 'q', |
[0x37] = 'w', |
[0x38] = 'e', |
[0x39] = 'r', |
[0x3a] = 't', |
[0x3b] = 'y', |
[0x3c] = 'u', |
[0x3d] = 'i', |
[0x3e] = 'o', |
[0x3f] = 'p', |
[0x40] = '[', |
[0x41] = ']', |
[0x42] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = SPECIAL, /* Control */ |
[0x4d] = 'a', |
[0x4e] = 's', |
[0x4f] = 'd', |
[0x50] = 'f', |
[0x51] = 'g', |
[0x52] = 'h', |
[0x53] = 'j', |
[0x54] = 'k', |
[0x55] = 'l', |
[0x56] = ';', |
[0x57] = '\'', |
[0x58] = '\\', |
[0x59] = '\n', /* Enter */ |
[0x5a] = '\n', /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'z', |
[0x65] = 'x', |
[0x66] = 'c', |
[0x67] = 'v', |
[0x68] = 'b', |
[0x69] = 'n', |
[0x6a] = 'm', |
[0x6b] = ',', |
[0x6c] = '.', |
[0x6d] = '/', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** Secondary meaning of scancodes. */ |
char sc_secondary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = SPECIAL, /* F1 */ |
[0x06] = SPECIAL, /* F2 */ |
[0x07] = SPECIAL, /* F10 */ |
[0x08] = SPECIAL, /* F3 */ |
[0x09] = SPECIAL, /* F11 */ |
[0x0a] = SPECIAL, /* F4 */ |
[0x0b] = SPECIAL, /* F12 */ |
[0x0c] = SPECIAL, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = SPECIAL, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = SPECIAL, /* F7 */ |
[0x11] = SPECIAL, /* F8 */ |
[0x12] = SPECIAL, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* Esc */ |
[0x1e] = '!', |
[0x1f] = '@', |
[0x20] = '#', |
[0x21] = '$', |
[0x22] = '%', |
[0x23] = '^', |
[0x24] = '&', |
[0x25] = '*', |
[0x26] = '(', |
[0x27] = ')', |
[0x28] = '_', |
[0x29] = '+', |
[0x2a] = '~', |
[0x2b] = SPECIAL, /* Backspace */ |
[0x2c] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* Home */ |
[0x35] = SPECIAL, /* Tab */ |
[0x36] = 'Q', |
[0x37] = 'W', |
[0x38] = 'E', |
[0x39] = 'R', |
[0x3a] = 'T', |
[0x3b] = 'Y', |
[0x3c] = 'U', |
[0x3d] = 'I', |
[0x3e] = 'O', |
[0x3f] = 'P', |
[0x40] = '{', |
[0x41] = '}', |
[0x42] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = SPECIAL, /* Control */ |
[0x4d] = 'A', |
[0x4e] = 'S', |
[0x4f] = 'D', |
[0x50] = 'F', |
[0x51] = 'G', |
[0x52] = 'H', |
[0x53] = 'J', |
[0x54] = 'K', |
[0x55] = 'L', |
[0x56] = ':', |
[0x57] = '"', |
[0x58] = '|', |
[0x59] = SPECIAL, /* Enter */ |
[0x5a] = SPECIAL, /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'Z', |
[0x65] = 'X', |
[0x66] = 'C', |
[0x67] = 'V', |
[0x68] = 'B', |
[0x69] = 'N', |
[0x6a] = 'M', |
[0x6b] = '<', |
[0x6c] = '>', |
[0x6d] = '?', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** @} |
*/ |
/branches/dd/kernel/genarch/src/mm/page_pt.c |
---|
76,7 → 76,7 |
if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL1_SIZE, FRAME_KA); |
memsetb(newpt, FRAME_SIZE << PTL1_SIZE, 0); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL1_SIZE, 0); |
SET_PTL1_ADDRESS(ptl0, PTL0_INDEX(page), KA2PA(newpt)); |
SET_PTL1_FLAGS(ptl0, PTL0_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
85,7 → 85,7 |
if (GET_PTL2_FLAGS(ptl1, PTL1_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL2_SIZE, FRAME_KA); |
memsetb(newpt, FRAME_SIZE << PTL2_SIZE, 0); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL2_SIZE, 0); |
SET_PTL2_ADDRESS(ptl1, PTL1_INDEX(page), KA2PA(newpt)); |
SET_PTL2_FLAGS(ptl1, PTL1_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
94,7 → 94,7 |
if (GET_PTL3_FLAGS(ptl2, PTL2_INDEX(page)) & PAGE_NOT_PRESENT) { |
newpt = (pte_t *)frame_alloc(PTL3_SIZE, FRAME_KA); |
memsetb(newpt, FRAME_SIZE << PTL3_SIZE, 0); |
memsetb((uintptr_t)newpt, FRAME_SIZE << PTL3_SIZE, 0); |
SET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page), KA2PA(newpt)); |
SET_PTL3_FLAGS(ptl2, PTL2_INDEX(page), PAGE_PRESENT | PAGE_USER | PAGE_EXEC | PAGE_CACHEABLE | PAGE_WRITE); |
} |
146,7 → 146,7 |
ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page))); |
/* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */ |
memsetb(&ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0); |
/* |
* Second, free all empty tables along the way from PTL3 down to PTL0. |
166,11 → 166,11 |
*/ |
frame_free(KA2PA((uintptr_t) ptl3)); |
if (PTL2_ENTRIES) |
memsetb(&ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0); |
else if (PTL1_ENTRIES) |
memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} else { |
/* |
* PTL3 is not empty. |
195,9 → 195,9 |
*/ |
frame_free(KA2PA((uintptr_t) ptl2)); |
if (PTL1_ENTRIES) |
memsetb(&ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0); |
else |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} |
else { |
/* |
223,7 → 223,7 |
* Release the frame and remove PTL1 pointer from preceding table. |
*/ |
frame_free(KA2PA((uintptr_t) ptl1)); |
memsetb(&ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
memsetb((uintptr_t) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0); |
} |
} |
/branches/dd/kernel/genarch/src/mm/as_pt.c |
---|
52,6 → 52,31 |
static void pt_lock(as_t *as, bool lock); |
static void pt_unlock(as_t *as, bool unlock); |
#ifdef __OBJC__ |
@implementation as_t |
+ (pte_t *) page_table_create: (int) flags |
{ |
return ptl0_create(flags); |
} |
+ (void) page_table_destroy: (pte_t *) page_table |
{ |
ptl0_destroy(page_table); |
} |
- (void) page_table_lock: (bool) _lock |
{ |
pt_lock(self, _lock); |
} |
- (void) page_table_unlock: (bool) unlock |
{ |
pt_unlock(self, unlock); |
} |
@end |
#else |
as_operations_t as_pt_operations = { |
.page_table_create = ptl0_create, |
.page_table_destroy = ptl0_destroy, |
58,6 → 83,7 |
.page_table_lock = pt_lock, |
.page_table_unlock = pt_unlock |
}; |
#endif |
/** Create PTL0. |
* |
77,7 → 103,7 |
table_size = FRAME_SIZE << PTL0_SIZE; |
if (flags & FLAG_AS_KERNEL) { |
memsetb(dst_ptl0, table_size, 0); |
memsetb((uintptr_t) dst_ptl0, table_size, 0); |
} else { |
uintptr_t src, dst; |
92,7 → 118,7 |
src = (uintptr_t) &src_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
dst = (uintptr_t) &dst_ptl0[PTL0_INDEX(KERNEL_ADDRESS_SPACE_START)]; |
memsetb(dst_ptl0, table_size, 0); |
memsetb((uintptr_t) dst_ptl0, table_size, 0); |
memcpy((void *) dst, (void *) src, table_size - (src - (uintptr_t) src_ptl0)); |
mutex_unlock(&AS_KERNEL->lock); |
interrupts_restore(ipl); |
/branches/dd/kernel/genarch/src/mm/asid.c |
---|
32,7 → 32,7 |
/** |
* @file |
* @brief ASID management. |
* @brief ASID management. |
* |
* Modern processor architectures optimize TLB utilization |
* by using ASIDs (a.k.a. memory contexts on sparc64 and |
/branches/dd/kernel/genarch/src/mm/as_ht.c |
---|
72,7 → 72,7 |
{ |
if (flags & FLAG_AS_KERNEL) { |
hash_table_create(&page_ht, PAGE_HT_ENTRIES, 2, &ht_operations); |
mutex_initialize(&page_ht_lock, MUTEX_PASSIVE); |
mutex_initialize(&page_ht_lock); |
} |
return NULL; |
} |
/branches/dd/kernel/genarch/src/acpi/acpi.c |
---|
49,12 → 49,8 |
struct acpi_rsdt *acpi_rsdt = NULL; |
struct acpi_xsdt *acpi_xsdt = NULL; |
struct acpi_signature_map signature_map[] = { |
{ |
(uint8_t *) "APIC", |
(void *) &acpi_madt, |
"Multiple APIC Description Table" |
} |
struct acpi_signature_map signature_map[] = { |
{ (uint8_t *)"APIC", (void *) &acpi_madt, "Multiple APIC Description Table" } |
}; |
static int rsdp_check(uint8_t *rsdp) { |
109,7 → 105,7 |
if (!acpi_sdt_check((uint8_t *) h)) |
goto next; |
*signature_map[j].sdt_ptr = h; |
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
printf("%#zp: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
} |
} |
next: |
130,7 → 126,7 |
if (!acpi_sdt_check((uint8_t *) h)) |
goto next; |
*signature_map[j].sdt_ptr = h; |
LOG("%p: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
printf("%#zp: ACPI %s\n", *signature_map[j].sdt_ptr, signature_map[j].description); |
} |
} |
next: |
164,7 → 160,7 |
return; |
rsdp_found: |
LOG("%p: ACPI Root System Description Pointer\n", acpi_rsdp); |
printf("%#zp: ACPI Root System Description Pointer\n", acpi_rsdp); |
acpi_rsdt = (struct acpi_rsdt *) (unative_t) acpi_rsdp->rsdt_address; |
if (acpi_rsdp->revision) acpi_xsdt = (struct acpi_xsdt *) ((uintptr_t) acpi_rsdp->xsdt_address); |
173,11 → 169,11 |
if (acpi_xsdt) map_sdt((struct acpi_sdt_header *) acpi_xsdt); |
if (acpi_rsdt && !acpi_sdt_check((uint8_t *) acpi_rsdt)) { |
printf("RSDT: bad checksum\n"); |
printf("RSDT: %s\n", "bad checksum"); |
return; |
} |
if (acpi_xsdt && !acpi_sdt_check((uint8_t *) acpi_xsdt)) { |
printf("XSDT: bad checksum\n"); |
printf("XSDT: %s\n", "bad checksum"); |
return; |
} |
/branches/dd/kernel/genarch/src/acpi/madt.c |
---|
126,7 → 126,7 |
int madt_irq_to_pin(unsigned int irq) |
{ |
ASSERT(irq < sizeof(isa_irq_map) / sizeof(int)); |
ASSERT(irq < sizeof(isa_irq_map)/sizeof(int)); |
return isa_irq_map[irq]; |
} |
184,15 → 184,15 |
case MADT_IO_SAPIC: |
case MADT_L_SAPIC: |
case MADT_PLATFORM_INTR_SRC: |
printf("MADT: skipping %s entry (type=%" PRIu8 ")\n", entry[h->type], h->type); |
printf("MADT: skipping %s entry (type=%zd)\n", entry[h->type], h->type); |
break; |
default: |
if (h->type >= MADT_RESERVED_SKIP_BEGIN && h->type <= MADT_RESERVED_SKIP_END) { |
printf("MADT: skipping reserved entry (type=%" PRIu8 ")\n", h->type); |
printf("MADT: skipping reserved entry (type=%zd)\n", h->type); |
} |
if (h->type >= MADT_RESERVED_OEM_BEGIN) { |
printf("MADT: skipping OEM entry (type=%" PRIu8 ")\n", h->type); |
printf("MADT: skipping OEM entry (type=%zd)\n", h->type); |
} |
break; |
} |
233,8 → 233,8 |
void madt_intr_src_ovrd_entry(struct madt_intr_src_ovrd *override, uint32_t index) |
{ |
ASSERT(override->source < sizeof(isa_irq_map) / sizeof(int)); |
printf("MADT: ignoring %s entry: bus=%" PRIu8 ", source=%" PRIu8 ", global_int=%" PRIu32 ", flags=%#" PRIx16 "\n", |
ASSERT(override->source < sizeof(isa_irq_map)/sizeof(int)); |
printf("MADT: ignoring %s entry: bus=%zd, source=%zd, global_int=%zd, flags=%#hx\n", |
entry[override->header.type], override->bus, override->source, |
override->global_int, override->flags); |
} |
/branches/dd/kernel/genarch/src/fb/logo-196x66.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/src/fb/fb.c |
---|
1,5 → 1,4 |
/* |
* Copyright (c) 2008 Martin Decky |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
27,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
34,7 → 33,6 |
*/ |
#include <genarch/fb/font-8x16.h> |
#include <genarch/fb/logo-196x66.h> |
#include <genarch/fb/visuals.h> |
#include <genarch/fb/fb.h> |
#include <console/chardev.h> |
41,7 → 39,6 |
#include <console/console.h> |
#include <sysinfo/sysinfo.h> |
#include <mm/slab.h> |
#include <align.h> |
#include <panic.h> |
#include <memstr.h> |
#include <config.h> |
50,116 → 47,137 |
#include <ddi/ddi.h> |
#include <arch/types.h> |
SPINLOCK_INITIALIZE(fb_lock); |
#include "helenos.xbm" |
static uint8_t *fb_addr; |
static uint8_t *backbuf; |
static uint8_t *glyphs; |
static uint8_t *bgscan; |
static parea_t fb_parea; /**< Physical memory area for fb. */ |
static unsigned int xres; |
static unsigned int yres; |
SPINLOCK_INITIALIZE(fb_lock); |
static unsigned int ylogo; |
static unsigned int ytrim; |
static unsigned int rowtrim; |
static uint8_t *fbaddress = NULL; |
static unsigned int scanline; |
static unsigned int glyphscanline; |
static uint8_t *blankline = NULL; |
static uint8_t *dbbuffer = NULL; /* Buffer for fast scrolling console */ |
static index_t dboffset; |
static unsigned int pixelbytes; |
static unsigned int glyphbytes; |
static unsigned int bgscanbytes; |
static unsigned int xres = 0; |
static unsigned int yres = 0; |
static unsigned int scanline = 0; |
static unsigned int pixelbytes = 0; |
#ifdef FB_INVERT_COLORS |
static bool invert_colors = true; |
#else |
static bool invert_colors = false; |
#endif |
static unsigned int cols; |
static unsigned int rows; |
static unsigned int position = 0; |
static unsigned int columns = 0; |
static unsigned int rows = 0; |
#define BG_COLOR 0x000080 |
#define FG_COLOR 0xffff00 |
#define COL_WIDTH 8 |
#define ROW_BYTES (scanline * FONT_SCANLINES) |
#define CURSOR 219 |
#define BGCOLOR 0x000080 |
#define FGCOLOR 0xffff00 |
#define LOGOCOLOR 0x2020b0 |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
#define COL2X(col) ((col) * FONT_WIDTH) |
#define ROW2Y(row) ((row) * FONT_SCANLINES) |
#define POINTPOS(x, y) ((y) * scanline + (x) * pixelbytes) |
#define X2COL(x) ((x) / FONT_WIDTH) |
#define Y2ROW(y) ((y) / FONT_SCANLINES) |
/***************************************************************/ |
/* Pixel specific fuctions */ |
#define FB_POS(x, y) ((y) * scanline + (x) * pixelbytes) |
#define BB_POS(col, row) ((row) * cols + (col)) |
#define GLYPH_POS(glyph, y) ((glyph) * glyphbytes + (y) * glyphscanline) |
static void (*rgb2scr)(void *, int); |
static int (*scr2rgb)(void *); |
static inline int COLOR(int color) |
{ |
return invert_colors ? ~color : color; |
} |
static void (*rgb_conv)(void *, uint32_t); |
/* Conversion routines between different color representations */ |
static void rgb_byte0888(void *dst, int rgb) |
{ |
*((int *) dst) = rgb; |
} |
static int byte0888_rgb(void *src) |
{ |
return (*((int *) src)) & 0xffffff; |
} |
/** ARGB 8:8:8:8 conversion |
* |
*/ |
static void rgb_0888(void *dst, uint32_t rgb) |
static void bgr_byte0888(void *dst, int rgb) |
{ |
*((uint32_t *) dst) = rgb & 0xffffff; |
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 | |
RED(rgb, 8); |
} |
static int byte0888_bgr(void *src) |
{ |
int color = *(uint32_t *)(src); |
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) | |
((color >> 16) & 0xff); |
} |
/** ABGR 8:8:8:8 conversion |
* |
*/ |
static void bgr_0888(void *dst, uint32_t rgb) |
static void rgb_byte888(void *dst, int rgb) |
{ |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8); |
uint8_t *scr = (uint8_t *) dst; |
#if defined(FB_INVERT_ENDIAN) |
scr[0] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[2] = BLUE(rgb, 8); |
#else |
scr[2] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[0] = BLUE(rgb, 8); |
#endif |
} |
static int byte888_rgb(void *src) |
{ |
uint8_t *scr = (uint8_t *) src; |
#if defined(FB_INVERT_ENDIAN) |
return scr[0] << 16 | scr[1] << 8 | scr[2]; |
#else |
return scr[2] << 16 | scr[1] << 8 | scr[0]; |
#endif |
} |
/** RGB 8:8:8 conversion |
* |
*/ |
static void rgb_888(void *dst, uint32_t rgb) |
/** 16-bit depth (5:5:5) */ |
static void rgb_byte555(void *dst, int rgb) |
{ |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
/* 5-bit, 5-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 | |
BLUE(rgb, 5); |
} |
/** BGR 8:8:8 conversion |
* |
*/ |
static void bgr_888(void *dst, uint32_t rgb) |
/** 16-bit depth (5:5:5) */ |
static int byte555_rgb(void *src) |
{ |
((uint8_t *) dst)[0] = RED(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = BLUE(rgb, 8); |
int color = *(uint16_t *)(src); |
return (((color >> 10) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3); |
} |
/** RGB 5:5:5 conversion |
* |
*/ |
static void rgb_555(void *dst, uint32_t rgb) |
/** 16-bit depth (5:6:5) */ |
static void rgb_byte565(void *dst, int rgb) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5); |
/* 5-bit, 6-bits, 5-bits */ |
*((uint16_t *) dst) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | |
BLUE(rgb, 5); |
} |
/** RGB 5:6:5 conversion |
* |
*/ |
static void rgb_565(void *dst, uint32_t rgb) |
/** 16-bit depth (5:6:5) */ |
static int byte565_rgb(void *src) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5); |
int color = *(uint16_t *)(src); |
return (((color >> 11) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3); |
} |
/** RGB 3:2:3 |
/** Put pixel - 8-bit depth (color palette/3:2:3) |
* |
* Even though we try 3:2:3 color scheme here, an 8-bit framebuffer |
* will most likely use a color palette. The color appearance |
166,162 → 184,246 |
* will be pretty random and depend on the default installed |
* palette. This could be fixed by supporting custom palette |
* and setting it to simulate the 8-bit truecolor. |
* |
* Currently we set the palette on the ia32, amd64 and sparc64 port. |
* |
* Note that the byte is being inverted by this function. The reason is |
* that we would like to use a color palette where the white color code |
* is 0 and the black color code is 255, as some machines (Sun Blade 1500) |
* use these codes for black and white and prevent to set codes |
* 0 and 255 to other colors. |
* |
*/ |
static void rgb_323(void *dst, uint32_t rgb) |
static void rgb_byte8(void *dst, int rgb) |
{ |
*((uint8_t *) dst) |
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3)); |
*((uint8_t *) dst) = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | |
BLUE(rgb, 3); |
} |
/** Hide logo and refresh screen |
/** Return pixel color - 8-bit depth (color palette/3:2:3) |
* |
* See the comment for rgb_byte(). |
*/ |
static void logo_hide(bool silent) |
static int byte8_rgb(void *src) |
{ |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
if (!silent) |
fb_redraw(); |
int color = *(uint8_t *)src; |
return (((color >> 5) & 0x7) << (16 + 5)) | |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5); |
} |
static void putpixel(unsigned int x, unsigned int y, int color) |
{ |
(*rgb2scr)(&fbaddress[POINTPOS(x, y)], COLOR(color)); |
/** Draw character at given position |
* |
*/ |
static void glyph_draw(uint8_t glyph, unsigned int col, unsigned int row, bool silent) |
if (dbbuffer) { |
int dline = (y + dboffset) % yres; |
(*rgb2scr)(&dbbuffer[POINTPOS(x, dline)], COLOR(color)); |
} |
} |
/** Get pixel from viewport */ |
static int getpixel(unsigned int x, unsigned int y) |
{ |
unsigned int x = COL2X(col); |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
if (y >= ytrim) |
logo_hide(silent); |
backbuf[BB_POS(col, row)] = glyph; |
if (!silent) { |
for (yd = 0; yd < FONT_SCANLINES; yd++) |
memcpy(&fb_addr[FB_POS(x, y + yd + ylogo)], |
&glyphs[GLYPH_POS(glyph, yd)], glyphscanline); |
if (dbbuffer) { |
int dline = (y + dboffset) % yres; |
return COLOR((*scr2rgb)(&dbbuffer[POINTPOS(x, dline)])); |
} |
return COLOR((*scr2rgb)(&fbaddress[POINTPOS(x, y)])); |
} |
/** Scroll screen down by one row |
* |
* |
*/ |
static void screen_scroll(bool silent) |
/** Fill screen with background color */ |
static void clear_screen(void) |
{ |
if (ylogo > 0) { |
logo_hide(silent); |
return; |
unsigned int y; |
for (y = 0; y < yres; y++) { |
memcpy(&fbaddress[scanline * y], blankline, xres * pixelbytes); |
if (dbbuffer) |
memcpy(&dbbuffer[scanline * y], blankline, |
xres * pixelbytes); |
} |
if (!silent) { |
unsigned int row; |
} |
/** Scroll screen one row up */ |
static void scroll_screen(void) |
{ |
if (dbbuffer) { |
count_t first; |
for (row = 0; row < rows; row++) { |
unsigned int y = ROW2Y(row); |
unsigned int yd; |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
unsigned int x; |
unsigned int col; |
for (col = 0, x = 0; col < cols; col++, |
x += FONT_WIDTH) { |
uint8_t glyph; |
if (row < rows - 1) { |
if (backbuf[BB_POS(col, row)] == |
backbuf[BB_POS(col, row + 1)]) |
continue; |
glyph = backbuf[BB_POS(col, row + 1)]; |
} else |
glyph = 0; |
memcpy(&fb_addr[FB_POS(x, y + yd)], |
&glyphs[GLYPH_POS(glyph, yd)], |
glyphscanline); |
} |
} |
/* Clear the last row */ |
memcpy(&dbbuffer[dboffset * scanline], blankline, ROW_BYTES); |
dboffset = (dboffset + FONT_SCANLINES) % yres; |
first = yres - dboffset; |
/* Move all rows one row up */ |
if (xres * pixelbytes == scanline) { |
memcpy(fbaddress, &dbbuffer[dboffset * scanline], |
first * scanline); |
memcpy(&fbaddress[first * scanline], dbbuffer, |
dboffset * scanline); |
} else { |
/* |
* When the scanline is bigger than number of bytes |
* in the X-resolution, chances are that the |
* frame buffer memory past the X-resolution is special |
* in some way. For example, the SUNW,ffb framebuffer |
* wraps this area around the beginning of the same |
* line. To avoid troubles, copy only memory as |
* specified by the resolution. |
*/ |
unsigned int i; |
for (i = 0; i < first; i++) |
memcpy(&fbaddress[i * scanline], |
&dbbuffer[(dboffset + i) * scanline], |
xres * pixelbytes); |
for (i = 0; i < dboffset; i++) |
memcpy(&fbaddress[(first + i) * scanline], |
&dbbuffer[i * scanline], xres * pixelbytes); |
} |
} else { |
uint8_t *lastline = &fbaddress[(rows - 1) * ROW_BYTES]; |
if (xres * pixelbytes == scanline) { |
/* Move all rows one row up */ |
memcpy((void *) fbaddress, |
(void *) &fbaddress[ROW_BYTES], |
scanline * yres - ROW_BYTES); |
/* Clear the last row */ |
memcpy((void *) lastline, (void *) blankline, |
ROW_BYTES); |
} else { |
/* |
* See the comment in the dbbuffer case. |
*/ |
unsigned int i; |
/* Move all rows one row up */ |
for (i = 0; i < yres - FONT_SCANLINES; i++) |
memcpy(&fbaddress[i * scanline], |
&fbaddress[(i + FONT_SCANLINES) * scanline], |
xres * pixelbytes); |
/* Clear the last row */ |
for (i = 0; i < FONT_SCANLINES; i++) |
memcpy(&lastline[i * scanline], |
&blankline[i * scanline], |
xres * pixelbytes); |
} |
} |
memmove(backbuf, backbuf + cols, cols * (rows - 1)); |
memsetb(&backbuf[BB_POS(0, rows - 1)], cols, 0); |
} |
static void cursor_put(bool silent) |
static void invert_pixel(unsigned int x, unsigned int y) |
{ |
glyph_draw(CURSOR, position % cols, position / cols, silent); |
putpixel(x, y, ~getpixel(x, y)); |
} |
static void cursor_remove(bool silent) |
/** Draw one line of glyph at a given position */ |
static void draw_glyph_line(unsigned int glline, unsigned int x, unsigned int y) |
{ |
glyph_draw(0, position % cols, position / cols, silent); |
unsigned int i; |
for (i = 0; i < 8; i++) |
if (glline & (1 << (7 - i))) { |
putpixel(x + i, y, FGCOLOR); |
} else |
putpixel(x + i, y, BGCOLOR); |
} |
/***************************************************************/ |
/* Character-console functions */ |
/** Draw character at given position */ |
static void draw_glyph(uint8_t glyph, unsigned int col, unsigned int row) |
{ |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) |
draw_glyph_line(fb_font[glyph * FONT_SCANLINES + y], |
col * COL_WIDTH, row * FONT_SCANLINES + y); |
} |
/** Invert character at given position */ |
static void invert_char(unsigned int col, unsigned int row) |
{ |
unsigned int x; |
unsigned int y; |
for (x = 0; x < COL_WIDTH; x++) |
for (y = 0; y < FONT_SCANLINES; y++) |
invert_pixel(col * COL_WIDTH + x, |
row * FONT_SCANLINES + y); |
} |
/** Draw character at default position */ |
static void draw_char(char chr) |
{ |
draw_glyph(chr, position % columns, position / columns); |
} |
static void draw_logo(unsigned int startx, unsigned int starty) |
{ |
unsigned int x; |
unsigned int y; |
unsigned int byte; |
unsigned int rowbytes; |
rowbytes = (helenos_width - 1) / 8 + 1; |
for (y = 0; y < helenos_height; y++) |
for (x = 0; x < helenos_width; x++) { |
byte = helenos_bits[rowbytes * y + x / 8]; |
byte >>= x % 8; |
if (byte & 1) |
putpixel(startx + x, starty + y, |
COLOR(LOGOCOLOR)); |
} |
} |
/***************************************************************/ |
/* Stdout specific functions */ |
static void invert_cursor(void) |
{ |
invert_char(position % columns, position / columns); |
} |
/** Print character to screen |
* |
* Emulate basic terminal commands. |
* |
* Emulate basic terminal commands |
*/ |
static void fb_putchar(chardev_t *dev, char ch, bool silent) |
static void fb_putchar(chardev_t *dev, char ch) |
{ |
spinlock_lock(&fb_lock); |
switch (ch) { |
case '\n': |
cursor_remove(silent); |
position += cols; |
position -= position % cols; |
invert_cursor(); |
position += columns; |
position -= position % columns; |
break; |
case '\r': |
cursor_remove(silent); |
position -= position % cols; |
invert_cursor(); |
position -= position % columns; |
break; |
case '\b': |
cursor_remove(silent); |
if (position % cols) |
invert_cursor(); |
if (position % columns) |
position--; |
break; |
case '\t': |
cursor_remove(silent); |
invert_cursor(); |
do { |
glyph_draw((uint8_t) ' ', position % cols, |
position / cols, silent); |
draw_char(' '); |
position++; |
} while ((position % 8) && (position < cols * rows)); |
} while ((position % 8) && position < columns * rows); |
break; |
default: |
glyph_draw((uint8_t) ch, position % cols, |
position / cols, silent); |
draw_char(ch); |
position++; |
} |
if (position >= cols * rows) { |
position -= cols; |
screen_scroll(silent); |
if (position >= columns * rows) { |
position -= columns; |
scroll_screen(); |
} |
cursor_put(silent); |
invert_cursor(); |
spinlock_unlock(&fb_lock); |
} |
332,97 → 434,6 |
}; |
/** Render glyphs |
* |
* Convert glyphs from device independent font |
* description to current visual representation. |
* |
*/ |
static void glyphs_render(void) |
{ |
/* Prerender glyphs */ |
unsigned int glyph; |
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) { |
unsigned int x; |
for (x = 0; x < FONT_WIDTH; x++) { |
void *dst = &glyphs[GLYPH_POS(glyph, y) + |
x * pixelbytes]; |
uint32_t rgb = (fb_font[ROW2Y(glyph) + y] & |
(1 << (7 - x))) ? FG_COLOR : BG_COLOR; |
rgb_conv(dst, rgb); |
} |
} |
} |
/* Prerender background scanline */ |
unsigned int x; |
for (x = 0; x < xres; x++) |
rgb_conv(&bgscan[x * pixelbytes], BG_COLOR); |
} |
/** Refresh the screen |
* |
*/ |
void fb_redraw(void) |
{ |
if (ylogo > 0) { |
unsigned int y; |
for (y = 0; y < LOGO_HEIGHT; y++) { |
unsigned int x; |
for (x = 0; x < xres; x++) |
rgb_conv(&fb_addr[FB_POS(x, y)], |
(x < LOGO_WIDTH) ? |
fb_logo[y * LOGO_WIDTH + x] : |
LOGO_COLOR); |
} |
} |
unsigned int row; |
for (row = 0; row < rowtrim; row++) { |
unsigned int y = ylogo + ROW2Y(row); |
unsigned int yd; |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
unsigned int x; |
unsigned int col; |
for (col = 0, x = 0; col < cols; |
col++, x += FONT_WIDTH) { |
void *d = &fb_addr[FB_POS(x, y + yd)]; |
void *s = &glyphs[GLYPH_POS(backbuf[BB_POS(col, |
row)], yd)]; |
memcpy(d, s, glyphscanline); |
} |
} |
} |
if (COL2X(cols) < xres) { |
unsigned int y; |
unsigned int size = (xres - COL2X(cols)) * pixelbytes; |
for (y = ylogo; y < yres; y++) |
memcpy(&fb_addr[FB_POS(COL2X(cols), y)], bgscan, size); |
} |
if (ROW2Y(rowtrim) + ylogo < yres) { |
unsigned int y; |
for (y = ROW2Y(rowtrim) + ylogo; y < yres; y++) |
memcpy(&fb_addr[FB_POS(0, y)], bgscan, bgscanbytes); |
} |
} |
/** Initialize framebuffer as a chardev output device |
* |
* @param addr Physical address of the framebuffer |
432,100 → 443,99 |
* @param visual Color model |
* |
*/ |
void fb_init(fb_properties_t *props) |
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan, |
unsigned int visual) |
{ |
switch (props->visual) { |
switch (visual) { |
case VISUAL_INDIRECT_8: |
rgb_conv = rgb_323; |
rgb2scr = rgb_byte8; |
scr2rgb = byte8_rgb; |
pixelbytes = 1; |
break; |
case VISUAL_RGB_5_5_5: |
rgb_conv = rgb_555; |
rgb2scr = rgb_byte555; |
scr2rgb = byte555_rgb; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5: |
rgb_conv = rgb_565; |
rgb2scr = rgb_byte565; |
scr2rgb = byte565_rgb; |
pixelbytes = 2; |
break; |
case VISUAL_RGB_8_8_8: |
rgb_conv = rgb_888; |
rgb2scr = rgb_byte888; |
scr2rgb = byte888_rgb; |
pixelbytes = 3; |
break; |
case VISUAL_BGR_8_8_8: |
rgb_conv = bgr_888; |
pixelbytes = 3; |
break; |
case VISUAL_RGB_8_8_8_0: |
rgb_conv = rgb_888; |
rgb2scr = rgb_byte888; |
scr2rgb = byte888_rgb; |
pixelbytes = 4; |
break; |
case VISUAL_RGB_0_8_8_8: |
rgb_conv = rgb_0888; |
rgb2scr = rgb_byte0888; |
scr2rgb = byte0888_rgb; |
pixelbytes = 4; |
break; |
case VISUAL_BGR_0_8_8_8: |
rgb_conv = bgr_0888; |
rgb2scr = bgr_byte0888; |
scr2rgb = byte0888_bgr; |
pixelbytes = 4; |
break; |
default: |
panic("Unsupported visual."); |
panic("Unsupported visual.\n"); |
} |
xres = props->x; |
yres = props->y; |
scanline = props->scan; |
unsigned int fbsize = scan * y; |
cols = X2COL(xres); |
rows = Y2ROW(yres); |
/* Map the framebuffer */ |
fbaddress = (uint8_t *) hw_map((uintptr_t) addr, fbsize); |
if (yres > ylogo) { |
ylogo = LOGO_HEIGHT; |
rowtrim = rows - Y2ROW(ylogo); |
if (ylogo % FONT_SCANLINES > 0) |
rowtrim--; |
ytrim = ROW2Y(rowtrim); |
} else { |
ylogo = 0; |
ytrim = yres; |
rowtrim = rows; |
} |
xres = x; |
yres = y; |
scanline = scan; |
glyphscanline = FONT_WIDTH * pixelbytes; |
glyphbytes = ROW2Y(glyphscanline); |
bgscanbytes = xres * pixelbytes; |
unsigned int fbsize = scanline * yres; |
unsigned int bbsize = cols * rows; |
unsigned int glyphsize = FONT_GLYPHS * glyphbytes; |
backbuf = (uint8_t *) malloc(bbsize, 0); |
if (!backbuf) |
panic("Unable to allocate backbuffer."); |
glyphs = (uint8_t *) malloc(glyphsize, 0); |
if (!glyphs) |
panic("Unable to allocate glyphs."); |
bgscan = malloc(bgscanbytes, 0); |
if (!bgscan) |
panic("Unable to allocate background pixel."); |
memsetb(backbuf, bbsize, 0); |
glyphs_render(); |
fb_addr = (uint8_t *) hw_map((uintptr_t) props->addr, fbsize); |
rows = y / FONT_SCANLINES; |
columns = x / COL_WIDTH; |
fb_parea.pbase = (uintptr_t) addr; |
fb_parea.vbase = (uintptr_t) fbaddress; |
fb_parea.frames = SIZE2FRAMES(fbsize); |
fb_parea.cacheable = false; |
ddi_parea_register(&fb_parea); |
sysinfo_set_item_val("fb", NULL, true); |
sysinfo_set_item_val("fb.kind", NULL, 1); |
sysinfo_set_item_val("fb.width", NULL, xres); |
sysinfo_set_item_val("fb.height", NULL, yres); |
sysinfo_set_item_val("fb.scanline", NULL, scanline); |
sysinfo_set_item_val("fb.visual", NULL, props->visual); |
sysinfo_set_item_val("fb.address.physical", NULL, props->addr); |
sysinfo_set_item_val("fb.scanline", NULL, scan); |
sysinfo_set_item_val("fb.visual", NULL, visual); |
sysinfo_set_item_val("fb.address.physical", NULL, addr); |
sysinfo_set_item_val("fb.invert-colors", NULL, invert_colors); |
/* Allocate double buffer */ |
unsigned int order = fnzb(SIZE2FRAMES(fbsize) - 1) + 1; |
dbbuffer = (uint8_t *) frame_alloc(order, FRAME_ATOMIC | FRAME_KA); |
if (!dbbuffer) |
printf("Failed to allocate scroll buffer.\n"); |
dboffset = 0; |
/* Initialized blank line */ |
blankline = (uint8_t *) malloc(ROW_BYTES, FRAME_ATOMIC); |
if (!blankline) |
panic("Failed to allocate blank line for framebuffer."); |
for (y = 0; y < FONT_SCANLINES; y++) |
for (x = 0; x < xres; x++) |
(*rgb2scr)(&blankline[POINTPOS(x, y)], COLOR(BGCOLOR)); |
fb_redraw(); |
clear_screen(); |
/* Update size of screen to match text area */ |
yres = rows * FONT_SCANLINES; |
draw_logo(xres - helenos_width, 0); |
invert_cursor(); |
chardev_initialize("fb", &framebuffer, &fb_ops); |
stdout = &framebuffer; |
} |
/branches/dd/kernel/genarch/src/fb/font-8x16.c |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
34,7 → 34,7 |
#include <genarch/fb/font-8x16.h> |
uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES] = { |
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = { |
/* 0 0x00 '^@' */ |
0x00, /* 00000000 */ |
/branches/dd/kernel/genarch/src/fb/helenos.xbm |
---|
0,0 → 1,163 |
#define helenos_width 127 |
#define helenos_height 120 |
static unsigned char helenos_bits[] = { |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x1f, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x80, 0x0f, 0x78, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0xc0, 0xc0, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7e, 0x00, 0x80, 0x81, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, |
0x0f, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x03, 0x01, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x00, 0x06, |
0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0x07, |
0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x0c, |
0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, |
0x00, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x80, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, |
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x03, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x7c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x80, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, |
0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x01, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x20, 0x00, 0x00, 0x00, |
0x00, 0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, |
0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x80, 0xc1, 0x00, 0x00, 0x00, |
0x00, 0xc0, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x80, |
0xc1, 0x00, 0x00, 0x00, 0x00, 0xf0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0xfe, 0x01, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, 0x83, 0x01, 0x00, 0x00, |
0x00, 0x1c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x03, 0x00, 0x00, |
0x03, 0x01, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x06, 0x03, 0x00, 0x00, |
0x08, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0x07, 0x00, 0x00, |
0x0c, 0x02, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0xff, 0x0f, 0x00, 0x00, 0x0c, 0x06, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0xfe, 0x0f, 0x00, 0x00, 0x18, 0x04, 0x00, 0x00, |
0x08, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, |
0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, |
0xfc, 0x1f, 0x00, 0x00, 0x18, 0x0c, 0x00, 0x00, 0x08, 0x03, 0x00, 0x00, |
0x80, 0x1f, 0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x30, 0x18, 0x00, 0x00, |
0x18, 0x02, 0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0xfc, 0x3f, 0x00, 0x00, |
0x30, 0x18, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, 0xe0, 0x7f, 0x00, 0x00, |
0xf8, 0x3f, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x18, 0x06, 0x00, 0x00, |
0xe0, 0x7f, 0x00, 0x00, 0xf8, 0x7f, 0x00, 0x00, 0x60, 0x30, 0x00, 0x00, |
0x38, 0x0c, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, |
0xe0, 0x20, 0x00, 0x00, 0x30, 0x0c, 0x00, 0x00, 0xe0, 0xff, 0x00, 0x00, |
0xf0, 0x7f, 0x00, 0x00, 0xc0, 0x78, 0x00, 0x00, 0x70, 0x08, 0x00, 0x00, |
0xe0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xc0, 0x7c, 0x00, 0x00, |
0x70, 0x18, 0x00, 0x00, 0xe0, 0xff, 0x01, 0x00, 0xf0, 0xff, 0x00, 0x00, |
0x80, 0xfd, 0x00, 0x00, 0x60, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, |
0xfc, 0xff, 0x01, 0x00, 0x80, 0xf9, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, |
0xc0, 0xff, 0x01, 0x80, 0xff, 0xff, 0x01, 0x00, 0x80, 0xfb, 0x00, 0x00, |
0xc0, 0x7f, 0x00, 0x00, 0xc0, 0xff, 0x03, 0xe0, 0xff, 0xff, 0x03, 0x00, |
0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0xfc, |
0xff, 0xff, 0x03, 0x00, 0x00, 0xf3, 0x01, 0x00, 0xc0, 0x7f, 0x00, 0x00, |
0x80, 0xff, 0x07, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0xf6, 0x03, 0x00, |
0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xe7, 0xff, 0xff, 0xff, 0x07, 0x00, |
0x00, 0xe6, 0x03, 0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, |
0xff, 0xff, 0x07, 0x00, 0x00, 0xec, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, |
0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, 0xcc, 0x07, 0x00, |
0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, 0x7f, 0xfe, 0x0f, 0x00, |
0x00, 0xdc, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0xff, 0xff, |
0x1f, 0xfe, 0x0f, 0x00, 0x00, 0xd8, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00, |
0x00, 0xfc, 0xff, 0xff, 0x03, 0xfe, 0x1f, 0x00, 0x00, 0x98, 0x0f, 0x00, |
0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0xff, 0xff, 0x00, 0xfc, 0x1f, 0x00, |
0x00, 0xb0, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x1f, |
0x00, 0xfc, 0x3f, 0x00, 0x00, 0x30, 0x1f, 0x00, 0x00, 0xfc, 0x07, 0x00, |
0x00, 0xf8, 0xff, 0x07, 0x00, 0xfc, 0x3f, 0x00, 0x00, 0x70, 0x1f, 0x00, |
0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0xff, 0x00, 0x00, 0xf8, 0x7f, 0x00, |
0x00, 0x60, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xf0, 0x7f, 0x00, |
0x00, 0xf8, 0x7f, 0x00, 0x00, 0xe0, 0x3e, 0x00, 0x00, 0xf8, 0x0f, 0x00, |
0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf0, 0x7f, 0x00, 0x00, 0xf8, 0x7e, 0x00, |
0x00, 0xf0, 0x1f, 0x00, 0x00, 0xf0, 0xff, 0x00, 0x00, 0xf0, 0xff, 0x00, |
0x00, 0xfc, 0x7c, 0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0xe0, 0xff, 0x00, |
0x00, 0xf0, 0xff, 0x00, 0x00, 0xfe, 0xfd, 0x00, 0x00, 0xf0, 0x1f, 0x00, |
0x00, 0xe0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00, 0x80, 0xff, 0xf9, 0x00, |
0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x01, 0x00, 0xe0, 0xff, 0x00, |
0xc0, 0xff, 0xfb, 0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0xc0, 0xff, 0x03, |
0x00, 0xc0, 0x7f, 0x00, 0xe0, 0xff, 0xfb, 0x01, 0x00, 0xc0, 0x7f, 0x00, |
0x00, 0x80, 0xff, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0xf8, 0xff, 0xf7, 0x01, |
0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x03, 0x00, 0x80, 0x3f, 0x00, |
0xfc, 0xff, 0xf7, 0x03, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x80, 0xff, 0x07, |
0x00, 0x00, 0x00, 0x00, 0xfe, 0xef, 0xe7, 0x03, 0x00, 0x80, 0xff, 0x00, |
0x00, 0x00, 0xff, 0x07, 0x00, 0x00, 0x00, 0x80, 0xff, 0xdf, 0xef, 0x07, |
0x00, 0x80, 0xff, 0x00, 0x00, 0x00, 0xff, 0x0f, 0x00, 0x00, 0x00, 0xc0, |
0xff, 0xdf, 0xef, 0x07, 0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xff, 0x0f, |
0x00, 0x00, 0x00, 0xe0, 0xff, 0xcf, 0xcf, 0x07, 0x00, 0x00, 0xff, 0x01, |
0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xf0, 0x7f, 0xc3, 0xcf, 0x0f, |
0x00, 0x00, 0xff, 0x01, 0x00, 0x00, 0xfe, 0x1f, 0x00, 0x00, 0x00, 0xfc, |
0xff, 0xe0, 0xcf, 0x0f, 0x00, 0x00, 0xfe, 0x03, 0x00, 0x00, 0xfc, 0x1f, |
0x00, 0x00, 0x00, 0xfe, 0xff, 0xf9, 0xc7, 0x0f, 0x00, 0x00, 0xfe, 0x03, |
0x00, 0x00, 0xfc, 0x1f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xe7, 0x0f, |
0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0xc0, 0xff, |
0xff, 0xff, 0xe7, 0x0f, 0x00, 0x00, 0xfc, 0x07, 0x00, 0x00, 0xf8, 0x07, |
0x00, 0x00, 0xe0, 0xff, 0xff, 0xff, 0xe3, 0x0f, 0x00, 0x00, 0xfc, 0x0f, |
0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0xff, 0xff, 0xff, 0xf1, 0x0f, |
0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, |
0xff, 0xff, 0xf8, 0x0f, 0x00, 0x00, 0xf8, 0x0f, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0xfe, 0xff, 0xff, 0x3f, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x1f, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x07, 0xfe, 0x0f, |
0x00, 0x00, 0xf0, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, |
0xff, 0x81, 0xff, 0x07, 0x00, 0x00, 0xf0, 0x3f, 0x00, 0x00, 0x00, 0x00, |
0x00, 0xe0, 0xff, 0xff, 0x3f, 0xe0, 0xff, 0x07, 0x00, 0x00, 0xe0, 0x3f, |
0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xff, 0xff, 0x07, 0xfc, 0xff, 0x07, |
0x00, 0x00, 0xe0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, |
0x80, 0xff, 0xff, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0x00, 0x00, 0x00, 0x00, |
0x00, 0xfe, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x01, 0x00, 0x00, 0xc0, 0x7f, |
0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0x07, 0xfe, 0xff, 0xff, 0x00, |
0x00, 0x00, 0xc0, 0x3f, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xc0, |
0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x80, 0xbf, 0x00, 0x00, 0x00, 0x00, |
0xe0, 0xff, 0x1f, 0xf0, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x80, 0xdf, |
0x00, 0x3c, 0x00, 0x00, 0xf0, 0xff, 0x03, 0xfe, 0xff, 0xff, 0x0f, 0x00, |
0x00, 0x00, 0x00, 0xcf, 0x00, 0x7e, 0x00, 0x00, 0xfc, 0x7f, 0xc0, 0xff, |
0xff, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x8f, 0x01, 0x7e, 0x00, 0x00, |
0xfe, 0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, |
0x01, 0x3e, 0x00, 0x00, 0xff, 0x03, 0xff, 0xff, 0xff, 0x0f, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x9e, 0x03, 0x00, 0x00, 0xc0, 0x7f, 0xc0, 0xff, 0xff, |
0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x03, 0x00, 0x00, 0xe0, |
0x0f, 0xf8, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, |
0x03, 0x00, 0x00, 0xf8, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x7c, 0x06, 0x00, 0x00, 0x3f, 0xe0, 0xff, 0xff, 0xff, |
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x0e, 0x00, 0xe0, 0x0f, |
0xfc, 0xff, 0xff, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, |
0x3c, 0x00, 0xfc, 0x01, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0xf8, 0x78, 0x80, 0x3f, 0xe0, 0xff, 0xff, 0xff, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, 0xe1, 0xff, 0x07, 0xfc, |
0xff, 0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf0, |
0x81, 0xff, 0x80, 0xff, 0xff, 0xff, 0x07, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0xf0, 0x03, 0x00, 0xf0, 0xff, 0xff, 0xff, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, 0x07, 0x00, 0xfe, 0xff, |
0xff, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xe0, |
0x0f, 0x00, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0xc0, 0x3f, 0xc0, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, 0xff, 0xff, 0xff, 0xff, |
0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc0, |
0xff, 0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x1f, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0xff, 0xff, 0xff, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0xfe, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x0f, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0xf0, 0xff, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x80, 0x3f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; |
/branches/dd/kernel/genarch/include/drivers/ega/ega.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/drivers/ns16550/ns16550.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/drivers/legacy/ia32/io.h |
---|
File deleted |
/branches/dd/kernel/genarch/include/drivers/i8042/i8042.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/drivers/z8530/z8530.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/kbrd/scanc_sun.h |
---|
File deleted |
/branches/dd/kernel/genarch/include/kbrd/kbrd.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/kbrd/scanc.h |
---|
File deleted |
/branches/dd/kernel/genarch/include/kbrd/scanc_pc.h |
---|
File deleted |
/branches/dd/kernel/genarch/include/kbrd |
---|
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/multiboot/multiboot.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/srln/srln.h |
---|
File deleted |
/branches/dd/kernel/genarch/include/ofw/ofw_tree.h |
---|
30,8 → 30,6 |
#define KERN_OFW_TREE_H_ |
#include <arch/types.h> |
#include <ddi/irq.h> |
#include <typedefs.h> |
#define OFW_TREE_PROPERTY_MAX_NAMELEN 32 |
44,11 → 42,11 |
ofw_tree_node_t *peer; |
ofw_tree_node_t *child; |
uint32_t node_handle; /**< Old OpenFirmware node handle. */ |
uint32_t node_handle; /**< Old OpenFirmware node handle. */ |
char *da_name; /**< Disambigued name. */ |
char *da_name; /**< Disambigued name. */ |
unsigned properties; /**< Number of properties. */ |
unsigned properties; /**< Number of properties. */ |
ofw_tree_property_t *property; |
/** |
106,7 → 104,7 |
uint32_t child_space; |
uint32_t child_base; |
uint32_t parent_space; |
uint64_t parent_base; /* group phys.mid and phys.lo together */ |
uint64_t parent_base; /* group phys.mid and phys.lo together */ |
uint32_t size; |
} __attribute__ ((packed)); |
typedef struct ofw_ebus_range ofw_ebus_range_t; |
128,8 → 126,8 |
typedef struct ofw_ebus_intr_mask ofw_ebus_intr_mask_t; |
struct ofw_pci_reg { |
uint32_t space; /* needs to be masked to obtain pure space id */ |
uint64_t addr; /* group phys.mid and phys.lo together */ |
uint32_t space; /* needs to be masked to obtain pure space id */ |
uint64_t addr; /* group phys.mid and phys.lo together */ |
uint64_t size; |
} __attribute__ ((packed)); |
typedef struct ofw_pci_reg ofw_pci_reg_t; |
136,7 → 134,7 |
struct ofw_pci_range { |
uint32_t space; |
uint64_t child_base; /* group phys.mid and phys.lo together */ |
uint64_t child_base; /* group phys.mid and phys.lo together */ |
uint64_t parent_base; |
uint64_t size; |
} __attribute__ ((packed)); |
161,43 → 159,27 |
} __attribute__ ((packed)); |
typedef struct ofw_upa_reg ofw_upa_reg_t; |
extern void ofw_tree_init(ofw_tree_node_t *); |
extern void ofw_tree_init(ofw_tree_node_t *root); |
extern void ofw_tree_print(void); |
extern const char *ofw_tree_node_name(const ofw_tree_node_t *); |
extern ofw_tree_node_t *ofw_tree_lookup(const char *); |
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *, |
const char *); |
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *, const char *); |
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *, |
const char *); |
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *, |
const char *); |
extern ofw_tree_node_t *ofw_tree_find_peer_by_name(ofw_tree_node_t *node, |
const char *name); |
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *, |
uint32_t); |
extern const char *ofw_tree_node_name(const ofw_tree_node_t *node); |
extern ofw_tree_node_t *ofw_tree_lookup(const char *path); |
extern ofw_tree_property_t *ofw_tree_getprop(const ofw_tree_node_t *node, const char *name); |
extern ofw_tree_node_t *ofw_tree_find_child(ofw_tree_node_t *node, const char *name); |
extern ofw_tree_node_t *ofw_tree_find_child_by_device_type(ofw_tree_node_t *node, const char *device_type); |
extern ofw_tree_node_t *ofw_tree_find_peer_by_device_type(ofw_tree_node_t *node, const char *device_type); |
extern ofw_tree_node_t *ofw_tree_find_node_by_handle(ofw_tree_node_t *root, uint32_t handle); |
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *, ofw_fhc_reg_t *, |
uintptr_t *); |
extern bool ofw_central_apply_ranges(ofw_tree_node_t *, ofw_central_reg_t *, |
uintptr_t *); |
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *, ofw_ebus_reg_t *, |
uintptr_t *); |
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *, ofw_pci_reg_t *, |
uintptr_t *); |
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *, ofw_sbus_reg_t *, |
uintptr_t *); |
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *, ofw_upa_reg_t *, |
uintptr_t *); |
extern bool ofw_fhc_apply_ranges(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uintptr_t *pa); |
extern bool ofw_central_apply_ranges(ofw_tree_node_t *node, ofw_central_reg_t *reg, uintptr_t *pa); |
extern bool ofw_ebus_apply_ranges(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uintptr_t *pa); |
extern bool ofw_pci_apply_ranges(ofw_tree_node_t *node, ofw_pci_reg_t *reg, uintptr_t *pa); |
extern bool ofw_sbus_apply_ranges(ofw_tree_node_t *node, ofw_sbus_reg_t *reg, uintptr_t *pa); |
extern bool ofw_upa_apply_ranges(ofw_tree_node_t *node, ofw_upa_reg_t *reg, uintptr_t *pa); |
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *, ofw_pci_reg_t *, |
ofw_pci_reg_t *); |
extern bool ofw_pci_reg_absolutize(ofw_tree_node_t *node, ofw_pci_reg_t *reg, ofw_pci_reg_t *out); |
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *, ofw_fhc_reg_t *, |
uint32_t, int *, cir_t *, void **); |
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *, ofw_ebus_reg_t *, |
uint32_t, int *, cir_t *, void **); |
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *, ofw_pci_reg_t *, |
int, int *, cir_t *, void **); |
extern bool ofw_fhc_map_interrupt(ofw_tree_node_t *node, ofw_fhc_reg_t *reg, uint32_t interrupt, int *inr); |
extern bool ofw_ebus_map_interrupt(ofw_tree_node_t *node, ofw_ebus_reg_t *reg, uint32_t interrupt, int *inr); |
extern bool ofw_pci_map_interrupt(ofw_tree_node_t *node, ofw_pci_reg_t *reg, int ino, int *inr); |
#endif |
/branches/dd/kernel/genarch/include/mm/page_pt.h |
---|
116,7 → 116,9 |
#define PTE_WRITABLE(p) PTE_WRITABLE_ARCH((p)) |
#define PTE_EXECUTABLE(p) PTE_EXECUTABLE_ARCH((p)) |
#ifndef __OBJC__ |
extern as_operations_t as_pt_operations; |
#endif |
extern page_mapping_operations_t pt_mapping_operations; |
extern void page_mapping_insert_pt(as_t *as, uintptr_t page, uintptr_t frame, |
/branches/dd/kernel/genarch/include/fb/logo-196x66.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/kernel/genarch/include/fb/fb.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
38,37 → 38,9 |
#include <arch/types.h> |
#include <synch/spinlock.h> |
/** |
* Properties of the framebuffer device. |
*/ |
typedef struct fb_properties { |
/** Physical address of the framebuffer device. */ |
uintptr_t addr; |
/** |
* Address where the first (top left) pixel is mapped, |
* relative to "addr". |
*/ |
unsigned int offset; |
/** Screen width in pixels. */ |
unsigned int x; |
/** Screen height in pixels. */ |
unsigned int y; |
/** Bytes per one scanline. */ |
unsigned int scan; |
/** Color model. */ |
unsigned int visual; |
} fb_properties_t; |
SPINLOCK_EXTERN(fb_lock); |
void fb_init(uintptr_t addr, unsigned int x, unsigned int y, unsigned int scan, unsigned int visual); |
void fb_redraw(void); |
void fb_init(fb_properties_t *props); |
#endif |
/** @} |
/branches/dd/kernel/genarch/include/fb/font-8x16.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
35,14 → 35,11 |
#ifndef KERN_FONT_8X16_H_ |
#define KERN_FONT_8X16_H_ |
#define FONT_GLYPHS 256 |
#define FONT_WIDTH 8 |
#define FONT_SCANLINES 16 |
#define FONT_GLIPHS 256 |
#define FONT_SCANLINES 16 |
#include <arch/types.h> |
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES]; |
extern uint8_t fb_font[FONT_GLYPHS * FONT_SCANLINES]; |
#endif |
/** @} |
/branches/dd/kernel/genarch/include/fb/visuals.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
35,16 → 35,15 |
#ifndef KERN_VISUALS_H_ |
#define KERN_VISUALS_H_ |
#define VISUAL_INDIRECT_8 0 |
#define VISUAL_INDIRECT_8 0 |
#define VISUAL_RGB_5_5_5 1 |
#define VISUAL_RGB_5_6_5 2 |
#define VISUAL_RGB_8_8_8 3 |
#define VISUAL_RGB_8_8_8_0 4 |
#define VISUAL_RGB_0_8_8_8 5 |
#define VISUAL_RGB_5_5_5 1 |
#define VISUAL_RGB_5_6_5 2 |
#define VISUAL_RGB_8_8_8 3 |
#define VISUAL_RGB_8_8_8_0 4 |
#define VISUAL_RGB_0_8_8_8 5 |
#define VISUAL_BGR_0_8_8_8 6 |
#define VISUAL_BGR_8_8_8 7 |
#define VISUAL_BGR_0_8_8_8 6 |
#endif |
/branches/dd/kernel/genarch/include/kbd/z8530.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Headers for Zilog 8530 serial port / keyboard driver. |
*/ |
#ifndef KERN_Z8530_H_ |
#define KERN_Z8530_H_ |
#include <console/chardev.h> |
#include <ipc/irq.h> |
extern bool z8530_belongs_to_kernel; |
extern void z8530_init(devno_t devno, inr_t inr, uintptr_t vaddr); |
extern void z8530_poll(void); |
extern void z8530_grab(void); |
extern void z8530_release(void); |
extern void z8530_interrupt(void); |
extern char z8530_key_read(chardev_t *d); |
extern irq_ownership_t z8530_claim(void); |
extern void z8530_irq_handler(irq_t *irq, void *arg, ...); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/ns16550.h |
---|
0,0 → 1,54 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Headers for NS 16550 serial port / keyboard driver. |
*/ |
#ifndef KERN_NS16550_H_ |
#define KERN_NS16550_H_ |
#include <console/chardev.h> |
#include <ipc/irq.h> |
extern void ns16550_init(devno_t devno, inr_t inr, uintptr_t vaddr); |
extern void ns16550_poll(void); |
extern void ns16550_grab(void); |
extern void ns16550_release(void); |
extern char ns16550_key_read(chardev_t *d); |
extern irq_ownership_t ns16550_claim(void); |
extern void ns16550_irq_handler(irq_t *irq, void *arg, ...); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/i8042.h |
---|
0,0 → 1,49 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KERN_I8042_H_ |
#define KERN_I8042_H_ |
#include <console/chardev.h> |
extern void i8042_init(devno_t kbd_devno, inr_t kbd_inr, devno_t mouse_devno, inr_t mouse_inr); |
extern void i8042_poll(void); |
extern void i8042_grab(void); |
extern void i8042_release(void); |
extern char i8042_key_read(chardev_t *d); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/key.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef KERN_KEY_H_ |
#define KERN_KEY_H_ |
#include <arch/types.h> |
#include <console/chardev.h> |
#define KEY_RELEASE 0x80 |
extern chardev_t kbrd; |
extern void key_released(uint8_t sc); |
extern void key_pressed(uint8_t sc); |
extern uint8_t active_read_buff_read(void); |
extern void active_read_buff_write(uint8_t ch); |
extern void active_read_key_pressed(uint8_t sc); |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/scanc_pc.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for pc keyboards. |
*/ |
#ifndef KERN_SCANC_PC_H_ |
#define KERN_SCANC_PC_H_ |
#define SC_ESC 0x01 |
#define SC_BACKSPACE 0x0e |
#define SC_LSHIFT 0x2a |
#define SC_RSHIFT 0x36 |
#define SC_CAPSLOCK 0x3a |
#define SC_SPEC_ESCAPE 0xe0 |
#define SC_LEFTARR 0x4b |
#define SC_RIGHTARR 0x4d |
#define SC_UPARR 0x48 |
#define SC_DOWNARR 0x50 |
#define SC_DELETE 0x53 |
#define SC_HOME 0x47 |
#define SC_END 0x4f |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/scanc_sun.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for sun keyboards. |
*/ |
#ifndef KERN_SCANC_SUN_H_ |
#define KERN_SCANC_SUN_H_ |
#define SC_ESC 0x1d |
#define SC_BACKSPACE 0x2b |
#define SC_LSHIFT 0x63 |
#define SC_RSHIFT 0x6e |
#define SC_CAPSLOCK 0x77 |
#define SC_SPEC_ESCAPE 0xe0 /* ??? */ |
#define SC_LEFTARR 0x18 |
#define SC_RIGHTARR 0x1c |
#define SC_UPARR 0x14 |
#define SC_DOWNARR 0x1b |
#define SC_DELETE 0x42 |
#define SC_HOME 0x34 |
#define SC_END 0x4a |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/include/kbd/scanc.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef KERN_SCANC_H_ |
#define KERN_SCANC_H_ |
#define SPECIAL '?' |
extern char sc_primary_map[]; |
extern char sc_secondary_map[]; |
#endif |
/** @} |
*/ |
/branches/dd/kernel/genarch/Makefile.inc |
---|
33,75 → 33,68 |
genarch/src/acpi/acpi.c \ |
genarch/src/acpi/madt.c |
endif |
ifeq ($(CONFIG_PAGE_PT),y) |
GENARCH_SOURCES += \ |
genarch/src/mm/page_pt.c \ |
genarch/src/mm/as_pt.c |
endif |
ifeq ($(CONFIG_PAGE_HT),y) |
GENARCH_SOURCES += \ |
genarch/src/mm/page_ht.c \ |
genarch/src/mm/as_ht.c |
endif |
ifeq ($(CONFIG_ASID),y) |
GENARCH_SOURCES += \ |
genarch/src/mm/asid.c |
endif |
ifeq ($(CONFIG_ASID_FIFO),y) |
GENARCH_SOURCES += \ |
genarch/src/mm/asid_fifo.c |
endif |
ifeq ($(CONFIG_SOFTINT),y) |
GENARCH_SOURCES += \ |
genarch/src/softint/division.c |
endif |
## Framebuffer |
ifeq ($(CONFIG_FB),y) |
GENARCH_SOURCES += \ |
genarch/src/fb/font-8x16.c \ |
genarch/src/fb/logo-196x66.c \ |
genarch/src/fb/fb.c |
DEFS += -DCONFIG_FB |
endif |
## i8042 controller |
ifeq ($(CONFIG_I8042),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/i8042/i8042.c |
genarch/src/kbd/i8042.c \ |
genarch/src/kbd/key.c \ |
genarch/src/kbd/scanc_pc.c |
endif |
ifeq ($(CONFIG_NS16550),y) |
## Sun keyboard |
ifeq ($(CONFIG_SUN_KBD),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/ns16550/ns16550.c |
genarch/src/kbd/key.c \ |
genarch/src/kbd/scanc_sun.c |
endif |
## z8530 controller |
ifeq ($(CONFIG_Z8530),y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/z8530/z8530.c |
genarch/src/kbd/z8530.c |
endif |
ifeq ($(CONFIG_PC_KBD),y) |
## ns16550 controller |
ifeq ($(CONFIG_NS16550),y) |
GENARCH_SOURCES += \ |
genarch/src/kbrd/kbrd.c \ |
genarch/src/kbrd/scanc_pc.c |
genarch/src/kbd/ns16550.c |
endif |
ifeq ($(CONFIG_SUN_KBD),y) |
GENARCH_SOURCES += \ |
genarch/src/kbrd/kbrd.c \ |
genarch/src/kbrd/scanc_sun.c |
endif |
ifeq ($(CONFIG_SRLN),y) |
## OpenFirmware Device Tree |
ifeq ($(CONFIG_OFW_TREE), y) |
GENARCH_SOURCES += \ |
genarch/src/srln/srln.c |
endif |
ifeq ($(CONFIG_OFW_TREE),y) |
GENARCH_SOURCES += \ |
genarch/src/ofw/ofw_tree.c \ |
genarch/src/ofw/ebus.c \ |
genarch/src/ofw/fhc.c \ |
109,13 → 102,3 |
genarch/src/ofw/sbus.c \ |
genarch/src/ofw/upa.c |
endif |
ifeq ($(CONFIG_MULTIBOOT), y) |
GENARCH_SOURCES += \ |
genarch/src/multiboot/multiboot.c |
endif |
ifeq ($(CONFIG_EGA), y) |
GENARCH_SOURCES += \ |
genarch/src/drivers/ega/ega.c |
endif |
/branches/dd/kernel/doc/AUTHORS |
---|
1,12 → 1,12 |
Jakub Jermar |
Martin Decky |
Ondrej Palkovsky |
Jiri Svoboda |
Jakub Vana |
Josef Cejka |
Michal Kebrt |
Sergey Bondari |
Pavel Jancik |
Petr Stepan |
Michal Konopa |
Jakub Jermar <jermar@helenos.eu> |
Martin Decky <decky@helenos.eu> |
Ondrej Palkovsky <palkovsky@helenos.eu> |
Jakub Vana <vana@helenos.eu> |
Josef Cejka <cejka@helenos.eu> |
Michal Kebrt <michalek.k@seznam.cz> |
Sergey Bondari <bondari@helenos.eu> |
Pavel Jancik <alfik.009@seznam.cz> |
Petr Stepan <stepan.petr@volny.cz> |
Michal Konopa <mkonopa@seznam.cz> |
Vojtech Mencl |
/branches/dd/kernel/doc/arch/mips32 |
---|
3,9 → 3,11 |
mips32 is the second port of SPARTAN kernel originally written by Jakub Jermar. |
It was first developed to run on MIPS R4000 32-bit simulator. |
Now it can run on real hardware as well. |
It can be compiled and run either as little- or big-endian. |
HARDWARE REQUIREMENTS |
o SGI Indy R4600 |
o emulated MIPS 4K CPU |
CPU |
/branches/dd/kernel/doc/BUGS_FOUND |
---|
0,0 → 1,23 |
During development of this operating system, there were found bugs in: |
Simics |
====== |
- ia32 BIOS rewrites memory during AP start in SMP environment (#3351) |
- ia32 Simics does not report #GP when EFER.NXE is 0 and finds NX page (#4214) |
- incorrect MIPS instructions MSUB, MSUBU |
Bochs |
===== |
- FXSAVE/FXRSTOR not working correctly with XMM registers (patch #1282033) |
Msim |
==== |
- Incorrect interpretation of lwl/lwr/swl/swr instructions |
- Omitted excMod case in write_proc_mem() |
- Incorrect signed multiplication |
Gcc |
=== |
- Incorrect generation of unaligned data access instructions |
(lwl/lwr/swl/swr) when using mipsel- target and -EB(big endian) |
compilation, -O2 (#23824) |
/branches/dd/uspace/dist/readme |
---|
File deleted |
/branches/dd/uspace/lib/libblock/libblock.c |
---|
File deleted |
/branches/dd/uspace/lib/libblock/libblock.h |
---|
File deleted |
/branches/dd/uspace/lib/libblock/Makefile |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/sparc64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/sparc64/include/ddi.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/sparc64/include/syscall.h |
---|
38,14 → 38,6 |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#define __syscall0 __syscall |
#define __syscall1 __syscall |
#define __syscall2 __syscall |
#define __syscall3 __syscall |
#define __syscall4 __syscall |
#define __syscall5 __syscall |
#define __syscall6 __syscall |
static inline sysarg_t |
__syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3, |
const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id) |
/branches/dd/uspace/lib/libc/arch/sparc64/include/config.h |
---|
37,6 → 37,7 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /**< Only one page color. */ |
#endif |
/branches/dd/uspace/lib/libc/arch/sparc64/src/entry.s |
---|
31,18 → 31,27 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# %o0 contains uarg |
# %o1 contains pcb_ptr |
# |
__entry: |
# Pass pcb_ptr as the first argument to __main() |
mov %o1, %o0 |
sethi %hi(_gp), %l7 |
call __main |
or %l7, %lo(_gp), %l7 |
call __io_init |
nop |
call main |
nop |
call __exit |
nop |
__entry_driver: |
sethi %hi(_gp), %l7 |
call __main |
or %l7, %lo(_gp), %l7 |
call main |
nop |
call __exit |
nop |
/branches/dd/uspace/lib/libc/arch/sparc64/Makefile.inc |
---|
30,10 → 30,10 |
# |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
ARCH_SOURCES += arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=ultrasparc -m64 |
LFLAGS += -no-check-sections -N |
/branches/dd/uspace/lib/libc/arch/ia64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/ia64/include/ddi.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/ia64/include/syscall.h |
---|
36,8 → 36,6 |
#ifndef LIBC_ia64_SYSCALL_H_ |
#define LIBC_ia64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dd/uspace/lib/libc/arch/ia64/include/config.h |
---|
36,7 → 36,8 |
#define LIBC_ia64_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/ia64/src/ddi.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/ia64/src/entry.s |
---|
31,17 → 31,27 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# r2 contains the PCB pointer |
# |
__entry: |
alloc loc0 = ar.pfs, 0, 1, 2, 0 |
movl r1 = _gp |
mov r1 = _gp |
br.call.sptk.many b0 = __main |
0: |
br.call.sptk.many b0 = __io_init |
1: |
br.call.sptk.many b0 = main |
2: |
br.call.sptk.many b0 = __exit |
# Pass PCB pointer as the first argument to __main |
mov out0 = r2 |
__entry_driver: |
alloc loc0 = ar.pfs, 0, 1, 2, 0 |
mov r1 = _gp |
br.call.sptk.many b0 = __main |
0: |
br.call.sptk.many b0 = main |
1: |
br.call.sptk.many b0 = __exit |
/branches/dd/uspace/lib/libc/arch/ia64/src/thread_entry.s |
---|
36,7 → 36,7 |
__thread_entry: |
alloc loc0 = ar.pfs, 0, 1, 1, 0 |
movl r1 = _gp |
mov r1 = _gp |
# |
# r8 contains address of uarg structure. |
/branches/dd/uspace/lib/libc/arch/ia64/Makefile.inc |
---|
30,15 → 30,14 |
# |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
TOOLCHAIN_DIR = /usr/local/ia64/bin |
CFLAGS += -fno-unwind-tables -DMALLOC_ALIGNMENT_16 |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/ddi.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
BFD_NAME = elf64-ia64-little |
BFD_ARCH = ia64-elf64 |
/branches/dd/uspace/lib/libc/arch/arm32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/arm32/include/ddi.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/arm32/include/byteorder.h |
---|
36,7 → 36,7 |
#ifndef LIBC_arm32_BYTEORDER_H_ |
#define LIBC_arm32_BYTEORDER_H_ |
#define ARCH_IS_LITTLE_ENDIAN |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/branches/dd/uspace/lib/libc/arch/arm32/include/syscall.h |
---|
30,14 → 30,12 |
* @{ |
*/ |
/** @file |
* @brief |
* @brief Empty. |
*/ |
#ifndef LIBC_arm32_SYSCALL_H_ |
#define LIBC_arm32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dd/uspace/lib/libc/arch/arm32/include/config.h |
---|
38,6 → 38,7 |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/arm32/src/entry.s |
---|
31,14 → 31,19 |
.org 0 |
.global __entry |
.global __entry_driver |
## User-space task entry point |
# |
# r1 contains the PCB pointer |
# |
__entry: |
# Pass pcb_ptr to __main as the first argument (in r0) |
mov r0, r1 |
bl __main |
bl __io_init |
bl main |
bl __exit |
__entry_driver: |
bl __main |
bl main |
bl __exit |
/branches/dd/uspace/lib/libc/arch/arm32/Makefile.inc |
---|
31,15 → 31,15 |
# |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
TOOLCHAIN_DIR = /usr/local/arm/bin |
CFLAGS += -ffixed-r9 -mtp=soft |
LFLAGS += -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS += |
AFLAGS += |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/eabi.S |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c \ |
arch/$(ARCH)/src/eabi.S |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
/branches/dd/uspace/lib/libc/arch/ppc32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/ppc32/include/ddi.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/ppc32/include/syscall.h |
---|
36,8 → 36,6 |
#ifndef LIBC_ppc32_SYSCALL_H_ |
#define LIBC_ppc32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dd/uspace/lib/libc/arch/ppc32/include/config.h |
---|
36,7 → 36,8 |
#define LIBC_ppc32_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/ppc32/src/entry.s |
---|
31,15 → 31,18 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# r6 contains the PCB pointer |
# |
__entry: |
# Pass the PCB pointer to __main() as the first argument. |
# The first argument is passed in r3. |
mr %r3, %r6 |
bl __main |
bl __io_init |
bl main |
bl __exit |
__entry_driver: |
bl __main |
bl main |
bl __exit |
/branches/dd/uspace/lib/libc/arch/ppc32/Makefile.inc |
---|
30,11 → 30,11 |
# |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=powerpc -msoft-float -m32 |
AFLAGS += -a32 |
/branches/dd/uspace/lib/libc/arch/amd64/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/amd64/include/atomic.h |
---|
38,11 → 38,11 |
#define LIBC_amd64_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) { |
asm volatile ("lock incq %0\n" : "+m" (val->count)); |
asm volatile ("lock incq %0\n" : "=m" (val->count)); |
} |
static inline void atomic_dec(atomic_t *val) { |
asm volatile ("lock decq %0\n" : "+m" (val->count)); |
asm volatile ("lock decq %0\n" : "=m" (val->count)); |
} |
static inline long atomic_postinc(atomic_t *val) |
52,7 → 52,7 |
asm volatile ( |
"movq $1, %0\n" |
"lock xaddq %0, %1\n" |
: "=r" (r), "+m" (val->count) |
: "=r" (r), "=m" (val->count) |
); |
return r; |
65,14 → 65,14 |
asm volatile ( |
"movq $-1, %0\n" |
"lock xaddq %0, %1\n" |
: "=r" (r), "+m" (val->count) |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
#endif |
/branches/dd/uspace/lib/libc/arch/amd64/include/syscall.h |
---|
36,8 → 36,6 |
#ifndef LIBC_amd64_SYSCALL_H_ |
#define LIBC_amd64_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dd/uspace/lib/libc/arch/amd64/include/config.h |
---|
36,7 → 36,8 |
#define LIBC_amd64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/amd64/src/entry.s |
---|
31,14 → 31,18 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# %rdi contains the PCB pointer |
# |
__entry: |
# %rdi was deliberately chosen as the first argument is also in %rdi |
# Pass PCB pointer to __main (no operation) |
call __main |
call __io_init |
call main |
call __exit |
__entry_driver: |
call __main |
call main |
call __exit |
/branches/dd/uspace/lib/libc/arch/amd64/Makefile.inc |
---|
30,11 → 30,11 |
# |
TARGET = amd64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/amd64/bin |
TOOLCHAIN_DIR = /usr/local/amd64/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
LFLAGS += -N |
/branches/dd/uspace/lib/libc/arch/ppc64/_link.ld.in |
---|
0,0 → 1,52 |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
text PT_LOAD FLAGS(5); |
data PT_LOAD FLAGS(6); |
} |
SECTIONS { |
. = 0x1000 + SIZEOF_HEADERS; |
.init : { |
*(.init); |
} :text |
.text : { |
*(.text); |
*(.toc); |
*(.rodata*); |
} :text |
. = . + 0x1000; |
.data : { |
*(.opd); |
*(.data*); |
*(.sdata); |
} :data |
.tdata : { |
_tdata_start = .; |
*(.tdata); |
_tdata_end = .; |
} :data |
.tbss : { |
_tbss_start = .; |
*(.tbss); |
_tbss_end = .; |
} :data |
_tls_alignment = MAX(ALIGNOF(.tdata), ALIGNOF(.tbss)); |
.bss : { |
*(.sbss); |
*(COMMON); |
*(.bss); |
} :data |
. = ALIGN(0x1000); |
_heap = .; |
/DISCARD/ : { |
*(*); |
} |
} |
/branches/dd/uspace/lib/libc/arch/ppc64/include/byteorder.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2005 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_BYTEORDER_H_ |
#define LIBC_ppc64_BYTEORDER_H_ |
#define ARCH_IS_BIG_ENDIAN |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/tls.h |
---|
0,0 → 1,73 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_TLS_H_ |
#define LIBC_ppc64_TLS_H_ |
#define CONFIG_TLS_VARIANT_1 |
#define PPC_TP_OFFSET 0x7000 |
typedef struct { |
void *fibril_data; |
} tcb_t; |
static inline void __tcb_set(tcb_t *tcb) |
{ |
void *tp = tcb; |
tp += PPC_TP_OFFSET + sizeof(tcb_t); |
asm volatile ( |
"mr %%r2, %0\n" |
: |
: "r" (tp) |
); |
} |
static inline tcb_t * __tcb_get(void) |
{ |
void * retval; |
asm volatile ( |
"mr %0, %%r2\n" |
: "=r" (retval) |
); |
return (tcb_t *)(retval - PPC_TP_OFFSET - sizeof(tcb_t)); |
} |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/thread.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_THREAD_H_ |
#define LIBC_ppc64_THREAD_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/types.h |
---|
0,0 → 1,55 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_TYPES_H_ |
#define LIBC_ppc64_TYPES_H_ |
typedef unsigned long sysarg_t; |
typedef char int8_t; |
typedef short int int16_t; |
typedef int int32_t; |
typedef long int int64_t; |
typedef unsigned char uint8_t; |
typedef unsigned short int uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long int uint64_t; |
typedef uint64_t uintptr_t; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/fibril.h |
---|
0,0 → 1,83 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_FIBRIL_H_ |
#define LIBC_ppc64_FIBRIL_H_ |
#include <sys/types.h> |
/* We define our own context_set, because we need to set |
* the TLS pointer to the tcb+0x7000 |
* |
* See tls_set in thread.h |
*/ |
#define context_set(c, _pc, stack, size, ptls) \ |
(c)->pc = (sysarg_t) (_pc); \ |
(c)->sp = ((sysarg_t) (stack)) + (size) - SP_DELTA; \ |
(c)->tls = ((sysarg_t) (ptls)) + 0x7000 + sizeof(tcb_t); |
#define SP_DELTA 16 |
typedef struct { |
uint64_t sp; |
uint64_t pc; |
uint64_t tls; |
uint64_t r13; |
uint64_t r14; |
uint64_t r15; |
uint64_t r16; |
uint64_t r17; |
uint64_t r18; |
uint64_t r19; |
uint64_t r20; |
uint64_t r21; |
uint64_t r22; |
uint64_t r23; |
uint64_t r24; |
uint64_t r25; |
uint64_t r26; |
uint64_t r27; |
uint64_t r28; |
uint64_t r29; |
uint64_t r30; |
uint64_t r31; |
uint64_t cr; |
} __attribute__ ((packed)) context_t; |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/atomic.h |
---|
0,0 → 1,95 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_ATOMIC_H_ |
#define LIBC_ppc64_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, 1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc"); |
} |
static inline void atomic_dec(atomic_t *val) |
{ |
long tmp; |
asm volatile ( |
"1:\n" |
"lwarx %0, 0, %2\n" |
"addic %0, %0, -1\n" |
"stwcx. %0, 0, %2\n" |
"bne- 1b" |
: "=&r" (tmp), "=m" (val->count) |
: "r" (&val->count), "m" (val->count) |
: "cc"); |
} |
static inline long atomic_postinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count - 1; |
} |
static inline long atomic_postdec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count + 1; |
} |
static inline long atomic_preinc(atomic_t *val) |
{ |
atomic_inc(val); |
return val->count; |
} |
static inline long atomic_predec(atomic_t *val) |
{ |
atomic_dec(val); |
return val->count; |
} |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/syscall.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libc |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef LIBC_ppc64_SYSCALL_H_ |
#define LIBC_ppc64_SYSCALL_H_ |
#include <syscall.h> |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/regname.h |
---|
0,0 → 1,188 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_REGNAME_H_ |
#define LIBC_ppc64_REGNAME_H_ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
#define cr1 1 |
#define cr2 2 |
#define cr3 3 |
#define cr4 4 |
#define cr5 5 |
#define cr6 6 |
#define cr7 7 |
/* General Purpose Registers (GPRs) */ |
#define r0 0 |
#define r1 1 |
#define r2 2 |
#define r3 3 |
#define r4 4 |
#define r5 5 |
#define r6 6 |
#define r7 7 |
#define r8 8 |
#define r9 9 |
#define r10 10 |
#define r11 11 |
#define r12 12 |
#define r13 13 |
#define r14 14 |
#define r15 15 |
#define r16 16 |
#define r17 17 |
#define r18 18 |
#define r19 19 |
#define r20 20 |
#define r21 21 |
#define r22 22 |
#define r23 23 |
#define r24 24 |
#define r25 25 |
#define r26 26 |
#define r27 27 |
#define r28 28 |
#define r29 29 |
#define r30 30 |
#define r31 31 |
/* GPR Aliases */ |
#define sp 1 |
/* Floating Point Registers (FPRs) */ |
#define fr0 0 |
#define fr1 1 |
#define fr2 2 |
#define fr3 3 |
#define fr4 4 |
#define fr5 5 |
#define fr6 6 |
#define fr7 7 |
#define fr8 8 |
#define fr9 9 |
#define fr10 10 |
#define fr11 11 |
#define fr12 12 |
#define fr13 13 |
#define fr14 14 |
#define fr15 15 |
#define fr16 16 |
#define fr17 17 |
#define fr18 18 |
#define fr19 19 |
#define fr20 20 |
#define fr21 21 |
#define fr22 22 |
#define fr23 23 |
#define fr24 24 |
#define fr25 25 |
#define fr26 26 |
#define fr27 27 |
#define fr28 28 |
#define fr29 29 |
#define fr30 30 |
#define fr31 31 |
#define vr0 0 |
#define vr1 1 |
#define vr2 2 |
#define vr3 3 |
#define vr4 4 |
#define vr5 5 |
#define vr6 6 |
#define vr7 7 |
#define vr8 8 |
#define vr9 9 |
#define vr10 10 |
#define vr11 11 |
#define vr12 12 |
#define vr13 13 |
#define vr14 14 |
#define vr15 15 |
#define vr16 16 |
#define vr17 17 |
#define vr18 18 |
#define vr19 19 |
#define vr20 20 |
#define vr21 21 |
#define vr22 22 |
#define vr23 23 |
#define vr24 24 |
#define vr25 25 |
#define vr26 26 |
#define vr27 27 |
#define vr28 28 |
#define vr29 29 |
#define vr30 30 |
#define vr31 31 |
#define evr0 0 |
#define evr1 1 |
#define evr2 2 |
#define evr3 3 |
#define evr4 4 |
#define evr5 5 |
#define evr6 6 |
#define evr7 7 |
#define evr8 8 |
#define evr9 9 |
#define evr10 10 |
#define evr11 11 |
#define evr12 12 |
#define evr13 13 |
#define evr14 14 |
#define evr15 15 |
#define evr16 16 |
#define evr17 17 |
#define evr18 18 |
#define evr19 19 |
#define evr20 20 |
#define evr21 21 |
#define evr22 22 |
#define evr23 23 |
#define evr24 24 |
#define evr25 25 |
#define evr26 26 |
#define evr27 27 |
#define evr28 28 |
#define evr29 29 |
#define evr30 30 |
#define evr31 31 |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/stackarg.h |
---|
0,0 → 1,41 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_STACKARG_H_ |
#define LIBC_STACKARG_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/faddr.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2005 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_FADDR_H_ |
#define LIBC_ppc64_FADDR_H_ |
#include <libarch/types.h> |
#define FADDR(fptr) ((uintptr_t) (fptr)) |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/limits.h |
---|
0,0 → 1,46 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_LIMITS_H_ |
#define LIBC_ppc64_LIMITS_H_ |
#define LONG_MIN MIN_INT64 |
#define LONG_MAX MAX_INT64 |
#define ULONG_MIN MIN_UINT64 |
#define ULONG_MAX MAX_UINT64 |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/include/config.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libppc64 |
* @{ |
*/ |
/** @file |
*/ |
#ifndef LIBC_ppc64_CONFIG_H_ |
#define LIBC_ppc64_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/src/fibril.S |
---|
0,0 → 1,62 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.global context_save |
.global context_restore |
#include <libarch/regname.h> |
#include <kernel/arch/context_offset.h> |
context_save: |
CONTEXT_SAVE_ARCH_CORE r3 |
mflr r4 |
stw r4, OFFSET_PC(r3) |
mfcr r4 |
stw r4, OFFSET_CR(r3) |
# context_save returns 1 |
li r3, 1 |
blr |
context_restore: |
CONTEXT_RESTORE_ARCH_CORE r3 |
lwz r4, OFFSET_CR(r3) |
mtcr r4 |
lwz r4, OFFSET_PC(r3) |
mtlr r4 |
# context_restore returns 0 |
li r3, 0 |
blr |
/branches/dd/uspace/lib/libc/arch/ppc64/src/syscall.c |
---|
0,0 → 1,66 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 ppc64 |
* @brief ppc64 architecture dependent parts of libc |
* @ingroup lc |
* @{ |
*/ |
/** @file |
*/ |
#include <libc.h> |
sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3, |
const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, const syscall_t id) |
{ |
register sysarg_t __ppc32_reg_r3 asm("3") = p1; |
register sysarg_t __ppc32_reg_r4 asm("4") = p2; |
register sysarg_t __ppc32_reg_r5 asm("5") = p3; |
register sysarg_t __ppc32_reg_r6 asm("6") = p4; |
register sysarg_t __ppc32_reg_r7 asm("7") = p5; |
register sysarg_t __ppc32_reg_r8 asm("8") = p6; |
register sysarg_t __ppc32_reg_r9 asm("9") = id; |
asm volatile ( |
"sc\n" |
: "=r" (__ppc32_reg_r3) |
: "r" (__ppc32_reg_r3), |
"r" (__ppc32_reg_r4), |
"r" (__ppc32_reg_r5), |
"r" (__ppc32_reg_r6), |
"r" (__ppc32_reg_r7), |
"r" (__ppc32_reg_r8), |
"r" (__ppc32_reg_r9) |
); |
return __ppc32_reg_r3; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/src/tls.c |
---|
0,0 → 1,60 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup libcppc64 |
* @{ |
*/ |
/** @file |
*/ |
#include <tls.h> |
#include <malloc.h> |
/** Allocate TLS & TCB for initial module threads |
* |
* @param data Start of data section |
* @return pointer to tcb_t structure |
* |
*/ |
tcb_t * __alloc_tls(void **data, size_t size) |
{ |
tcb_t *tcb; |
*data = malloc(sizeof(tcb_t) + size); |
tcb = (tcb_t *) (*data + size); |
return tcb; |
} |
void __free_tls_arch(tcb_t *tcb, size_t size) |
{ |
void *start = ((void *) tcb) - size; |
free(start); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/arch/ppc64/src/entry.s |
---|
0,0 → 1,48 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.section .init, "ax" |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# |
__entry: |
bl __main |
bl __io_init |
bl main |
bl __exit |
__entry_driver: |
bl __main |
bl main |
bl __exit |
/branches/dd/uspace/lib/libc/arch/ppc64/src/thread_entry.s |
---|
0,0 → 1,39 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.text |
.globl __thread_entry |
## User-space thread entry point for all but the first threads. |
# |
# |
__thread_entry: |
b __thread_main |
.end __thread_entry |
/branches/dd/uspace/lib/libc/arch/ppc64/Makefile.inc |
---|
0,0 → 1,44 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## Toolchain configuration |
# |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
CFLAGS += -mcpu=powerpc64 -msoft-float -m64 |
AFLAGS += -a64 |
LFLAGS += -N |
BFD_NAME = elf64-powerpc |
BFD_ARCH = powerpc:common64 |
/branches/dd/uspace/lib/libc/arch/mips32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/mips32/include/ddi.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/arch/mips32/include/atomic.h |
---|
59,14 → 59,13 |
asm volatile ( |
"1:\n" |
" ll %0, %1\n" |
" addu %0, %0, %3\n" /* same as add, but never traps on overflow */ |
" addiu %0, %0, %3\n" /* same as addi, but never traps on overflow */ |
" move %2, %0\n" |
" sc %0, %1\n" |
" beq %0, %4, 1b\n" /* if the atomic operation failed, try again */ |
/* nop */ /* nop is inserted automatically by compiler */ |
" nop\n" |
: "=&r" (tmp), "+m" (val->count), "=&r" (v) |
: "r" (i), "i" (0) |
: "=r" (tmp), "=m" (val->count), "=r" (v) |
: "i" (i), "i" (0) |
); |
return v; |
/branches/dd/uspace/lib/libc/arch/mips32/include/syscall.h |
---|
36,8 → 36,6 |
#ifndef LIBC_mips32_SYSCALL_H_ |
#define LIBC_mips32_SYSCALL_H_ |
#define LIBARCH_SYSCALL_GENERIC |
#include <syscall.h> |
#endif |
/branches/dd/uspace/lib/libc/arch/mips32/include/config.h |
---|
36,7 → 36,8 |
#define LIBC_mips32_CONFIG_H_ |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/mips32/src/entry.s |
---|
35,13 → 35,13 |
## User-space task entry point |
# |
# $a0 ($4) contains the PCB pointer |
# |
.ent __entry |
__entry: |
.frame $sp, 32, $31 |
.cpload $25 |
# Mips o32 may store its arguments on stack, make space (16 bytes), |
# so that it could work with -O0 |
# Make space additional 16 bytes for the stack frame |
48,18 → 48,42 |
addiu $sp, -32 |
.cprestore 16 # Allow PIC code |
jal __main |
nop |
jal __io_init |
nop |
jal main |
nop |
jal __exit |
nop |
.end |
# Pass pcb_ptr to __main() as the first argument. pcb_ptr is already |
# in $a0. As the first argument is passed in $a0, no operation |
# is needed. |
.ent __entry_driver |
__entry_driver: |
.frame $sp, 32, $31 |
.cpload $25 |
# Mips o32 may store its arguments on stack, make space (16 bytes), |
# so that it could work with -O0 |
# Make space additional 16 bytes for the stack frame |
addiu $sp, -32 |
.cprestore 16 # Allow PIC code |
jal __main |
nop |
jal main |
nop |
jal __exit |
nop |
.end |
# Alignment of output section data to 0x4000 |
.section .data |
.align 14 |
/branches/dd/uspace/lib/libc/arch/mips32/Makefile.inc |
---|
30,12 → 30,18 |
# |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
TOOLCHAIN_DIR = /usr/local/mipsel/bin |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
-include ../../Makefile.config |
ifeq ($(CONFIG_MIPS_FPU),y) |
CFLAGS += -DCONFIG_MIPS_FPU |
endif |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
BFD_ARCH = mips |
BFD_NAME = elf32-tradlittlemips |
/branches/dd/uspace/lib/libc/arch/ia32/_link.ld.in |
---|
1,4 → 1,4 |
STARTUP(LIBC_PREFIX/arch/UARCH/src/entry.o) |
STARTUP(LIBC_PREFIX/arch/ARCH/src/entry.o) |
ENTRY(__entry) |
PHDRS { |
/branches/dd/uspace/lib/libc/arch/ia32/include/atomic.h |
---|
36,11 → 36,11 |
#define LIBC_ia32_ATOMIC_H_ |
static inline void atomic_inc(atomic_t *val) { |
asm volatile ("lock incl %0\n" : "+m" (val->count)); |
asm volatile ("lock incl %0\n" : "=m" (val->count)); |
} |
static inline void atomic_dec(atomic_t *val) { |
asm volatile ("lock decl %0\n" : "+m" (val->count)); |
asm volatile ("lock decl %0\n" : "=m" (val->count)); |
} |
static inline long atomic_postinc(atomic_t *val) |
50,7 → 50,7 |
asm volatile ( |
"movl $1, %0\n" |
"lock xaddl %0, %1\n" |
: "=r" (r), "+m" (val->count) |
: "=r" (r), "=m" (val->count) |
); |
return r; |
63,14 → 63,14 |
asm volatile ( |
"movl $-1, %0\n" |
"lock xaddl %0, %1\n" |
: "=r" (r), "+m" (val->count) |
: "=r" (r), "=m" (val->count) |
); |
return r; |
} |
#define atomic_preinc(val) (atomic_postinc(val) + 1) |
#define atomic_predec(val) (atomic_postdec(val) - 1) |
#define atomic_preinc(val) (atomic_postinc(val)+1) |
#define atomic_predec(val) (atomic_postdec(val)-1) |
#endif |
/branches/dd/uspace/lib/libc/arch/ia32/include/syscall.h |
---|
36,25 → 36,8 |
#ifndef LIBC_ia32_SYSCALL_H_ |
#define LIBC_ia32_SYSCALL_H_ |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#include <syscall.h> |
#define __syscall0 __syscall_sysenter |
#define __syscall1 __syscall_sysenter |
#define __syscall2 __syscall_sysenter |
#define __syscall3 __syscall_sysenter |
#define __syscall4 __syscall_sysenter |
#define __syscall5 __syscall_int |
#define __syscall6 __syscall_int |
extern sysarg_t |
__syscall_sysenter(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, |
const sysarg_t, const sysarg_t, const syscall_t); |
extern sysarg_t |
__syscall_int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t, |
const sysarg_t, const sysarg_t, const syscall_t); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/arch/ia32/include/ddi.h |
---|
33,72 → 33,43 |
#ifndef LIBC_ia32_DDI_H_ |
#define LIBC_ia32_DDI_H_ |
#include <sys/types.h> |
#include <libarch/types.h> |
static inline void outb(int16_t port, uint8_t b) |
{ |
asm volatile ("outb %0, %1\n" :: "a" (b), "d" (port)); |
} |
#define IO_SPACE_BOUNDARY ((void *) (64 * 1024)) |
static inline uint8_t pio_read_8(ioport8_t *port) |
static inline void outw(int16_t port, int16_t w) |
{ |
uint8_t val; |
asm volatile ( |
"inb %w[port], %b[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
asm volatile ("outw %0, %1\n" :: "a" (w), "d" (port)); |
} |
static inline uint16_t pio_read_16(ioport16_t *port) |
static inline void outl(int16_t port, uint32_t l) |
{ |
uint16_t val; |
asm volatile ( |
"inw %w[port], %w[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
return val; |
asm volatile ("outl %0, %1\n" :: "a" (l), "d" (port)); |
} |
static inline uint32_t pio_read_32(ioport32_t *port) |
static inline uint8_t inb(int16_t port) |
{ |
uint32_t val; |
asm volatile ( |
"inl %w[port], %[val]\n" |
: [val] "=a" (val) |
: [port] "d" (port) |
); |
uint8_t val; |
asm volatile ("inb %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
static inline void pio_write_8(ioport8_t *port, uint8_t val) |
static inline int16_t inw(int16_t port) |
{ |
asm volatile ( |
"outb %b[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
int16_t val; |
asm volatile ("inw %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
static inline void pio_write_16(ioport16_t *port, uint16_t val) |
static inline uint32_t inl(int16_t port) |
{ |
asm volatile ( |
"outw %w[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
} |
uint32_t val; |
static inline void pio_write_32(ioport32_t *port, uint32_t val) |
{ |
asm volatile ( |
"outl %[val], %w[port]\n" |
:: [val] "a" (val), [port] "d" (port) |
); |
asm volatile ("inl %1, %0 \n" : "=a" (val) : "d"(port)); |
return val; |
} |
#endif |
/branches/dd/uspace/lib/libc/arch/ia32/include/config.h |
---|
36,7 → 36,8 |
#define LIBC_ia32_CONFIG_H_ |
#define PAGE_WIDTH 12 |
#define PAGE_SIZE (1 << PAGE_WIDTH) |
#define PAGE_SIZE (1<<PAGE_WIDTH) |
#define PAGE_COLOR_BITS 0 /* dummy */ |
#endif |
/branches/dd/uspace/lib/libc/arch/ia32/src/syscall.S |
---|
28,14 → 28,14 |
.text |
/** Syscall wrapper - INT $0x30 version. |
/** Syscall wrapper. |
* |
* Mind the order of arguments. First two arguments and the syscall number go to |
* scratch registers. An optimized version of this wrapper for fewer arguments |
* could benefit from this and not save unused registers on the stack. |
*/ |
.global __syscall_int |
__syscall_int: |
.global __syscall |
__syscall: |
pushl %ebx |
pushl %esi |
pushl %edi |
54,37 → 54,3 |
popl %ebx |
ret |
/** Syscall wrapper - SYSENTER version. |
* |
* This is an optimized version of syscall for four or less arguments. Note |
* that EBP and EDI are used to remember user stack address and the return |
* address. The kernel part doesn't save DS, ES and FS so the handler restores |
* these to the selector immediately following CS (it must be the flat data |
* segment, otherwise the SYSENTER wouldn't work in the first place). |
*/ |
.global __syscall_sysenter |
__syscall_sysenter: |
pushl %ebx |
pushl %esi |
pushl %edi |
pushl %ebp |
mov %esp, %ebp |
lea ra, %edi |
movl 20(%esp), %edx # First argument. |
movl 24(%esp), %ecx # Second argument. |
movl 28(%esp), %ebx # Third argument. |
movl 32(%esp), %esi # Fourth argument. |
movl 44(%esp), %eax # Syscall number. |
sysenter |
ra: |
movw %cs, %cx |
addw $8, %cx |
movw %cx, %ds |
movw %cx, %es |
movw %cx, %fs |
popl %ebp |
popl %edi |
popl %esi |
popl %ebx |
ret |
/branches/dd/uspace/lib/libc/arch/ia32/src/entry.s |
---|
31,10 → 31,10 |
.org 0 |
.globl __entry |
.globl __entry_driver |
## User-space task entry point |
# |
# %ebx contains the PCB pointer |
# |
__entry: |
mov %ss, %ax |
42,9 → 42,19 |
mov %ax, %es |
mov %ax, %fs |
# Do not set %gs, it contains descriptor that can see TLS |
# Pass the PCB pointer to __main as the first argument |
pushl %ebx |
call __main |
call __io_init |
call main |
call __exit |
__entry_driver: |
mov %ss, %ax |
mov %ax, %ds |
mov %ax, %es |
mov %ax, %fs |
# Do not set %gs, it contains descriptor that can see TLS |
call __main |
call main |
call __exit |
/branches/dd/uspace/lib/libc/arch/ia32/Makefile.inc |
---|
30,12 → 30,12 |
# |
TARGET = i686-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/i686/bin |
TOOLCHAIN_DIR = /usr/local/i686/bin |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.S \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c \ |
arch/$(UARCH)/src/setjmp.S |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.S \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c \ |
arch/$(ARCH)/src/setjmp.S |
LFLAGS += -N |
/branches/dd/uspace/lib/libc/arch/mips32eb/Makefile.inc |
---|
30,12 → 30,12 |
# |
TARGET = mips-sgi-irix5 |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mips/bin |
TOOLCHAIN_DIR = /usr/local/mips/bin |
CFLAGS += -mips3 |
ARCH_SOURCES += arch/$(UARCH)/src/syscall.c \ |
arch/$(UARCH)/src/fibril.S \ |
arch/$(UARCH)/src/tls.c |
ARCH_SOURCES += arch/$(ARCH)/src/syscall.c \ |
arch/$(ARCH)/src/fibril.S \ |
arch/$(ARCH)/src/tls.c |
LFLAGS += -N |
/branches/dd/uspace/lib/libc/include/console.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/smc.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/loader/pcb.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/loader/loader.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/console/color.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/console/style.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/macros.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/getopt.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/mem.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/uspace/lib/libc/include/kbd/kbd.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/kbd/keycode.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/udebug.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/ipc/bus.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/ipc/console.h |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/uspace/lib/libc/include/ipc/devmap.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/ipc/loader.h |
---|
File deleted |
/branches/dd/uspace/lib/libc/include/ipc/ipc.h |
---|
47,7 → 47,8 |
} ipc_call_t; |
typedef sysarg_t ipc_callid_t; |
typedef void (* ipc_async_callback_t)(void *, int, ipc_call_t *); |
typedef void (* ipc_async_callback_t)(void *private, int retval, |
ipc_call_t *data); |
/* |
* User-friendly wrappers for ipc_call_sync_fast() and ipc_call_sync_slow(). |
172,20 → 173,22 |
ipc_call_sync_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
(arg4), (arg5), (res1), (res2), (res3), (res4), (res5)) |
extern int ipc_call_sync_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *); |
extern int ipc_call_sync_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t *result1, ipcarg_t *result2, |
ipcarg_t *result3, ipcarg_t *result4, ipcarg_t *result5); |
extern int ipc_call_sync_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t *, ipcarg_t *, ipcarg_t *, ipcarg_t *, |
ipcarg_t *); |
extern int ipc_call_sync_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
ipcarg_t *result1, ipcarg_t *result2, ipcarg_t *result3, ipcarg_t *result4, |
ipcarg_t *result5); |
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *, uint32_t, int); |
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *, uint32_t); |
extern ipc_callid_t ipc_wait_cycle(ipc_call_t *call, uint32_t usec, int flags); |
extern ipc_callid_t ipc_wait_for_call_timeout(ipc_call_t *data, uint32_t usec); |
static inline ipc_callid_t ipc_wait_for_call(ipc_call_t *data) |
{ |
return ipc_wait_for_call_timeout(data, SYNCH_NO_TIMEOUT); |
} |
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *); |
extern ipc_callid_t ipc_trywait_for_call(ipc_call_t *data); |
/* |
* User-friendly wrappers for ipc_answer_fast() and ipc_answer_slow(). |
206,10 → 209,10 |
#define ipc_answer_5(callid, retval, arg1, arg2, arg3, arg4, arg5) \ |
ipc_answer_slow((callid), (retval), (arg1), (arg2), (arg3), (arg4), (arg5)) |
extern ipcarg_t ipc_answer_fast(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t); |
extern ipcarg_t ipc_answer_slow(ipc_callid_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t); |
extern ipcarg_t ipc_answer_fast(ipc_callid_t callid, ipcarg_t retval, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4); |
extern ipcarg_t ipc_answer_slow(ipc_callid_t callid, ipcarg_t retval, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5); |
/* |
* User-friendly wrappers for ipc_call_async_fast() and ipc_call_async_slow(). |
217,7 → 220,8 |
* arguments. The macros decide between the fast and the slow version according |
* to m. |
*/ |
#define ipc_call_async_0(phoneid, method, private, callback, can_preempt) \ |
#define ipc_call_async_0(phoneid, method, private, callback, \ |
can_preempt) \ |
ipc_call_async_fast((phoneid), (method), 0, 0, 0, 0, (private), \ |
(callback), (can_preempt)) |
#define ipc_call_async_1(phoneid, method, arg1, private, callback, \ |
241,24 → 245,23 |
ipc_call_async_slow((phoneid), (method), (arg1), (arg2), (arg3), \ |
(arg4), (arg5), (private), (callback), (can_preempt)) |
extern void ipc_call_async_fast(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, void *, ipc_async_callback_t, int); |
extern void ipc_call_async_slow(int, ipcarg_t, ipcarg_t, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, void *, ipc_async_callback_t, int); |
extern void ipc_call_async_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, void *private, |
ipc_async_callback_t callback, int can_preempt); |
extern void ipc_call_async_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, void *private, |
ipc_async_callback_t callback, int can_preempt); |
#define IPC_FLAG_BLOCKING 0x01 |
extern int ipc_connect_to_me(int phoneid, int arg1, int arg2, int arg3, |
ipcarg_t *phone); |
extern int ipc_connect_me_to(int phoneid, int arg1, int arg2, int arg3); |
extern int ipc_hangup(int phoneid); |
extern int ipc_register_irq(int inr, int devno, int method, irq_code_t *code); |
extern int ipc_unregister_irq(int inr, int devno); |
extern int ipc_forward_fast(ipc_callid_t callid, int phoneid, int method, |
ipcarg_t arg1, ipcarg_t arg2, int mode); |
extern int ipc_connect_to_me(int, int, int, int, ipcarg_t *); |
extern int ipc_connect_me_to(int, int, int, int); |
extern int ipc_connect_me_to_blocking(int, int, int, int); |
extern int ipc_hangup(int); |
extern int ipc_register_irq(int, int, int, irq_code_t *); |
extern int ipc_unregister_irq(int, int); |
extern int ipc_forward_fast(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, int); |
extern int ipc_forward_slow(ipc_callid_t, int, int, ipcarg_t, ipcarg_t, |
ipcarg_t, ipcarg_t, ipcarg_t, int); |
/* |
* User-friendly wrappers for ipc_share_in_start(). |
*/ |
271,23 → 274,20 |
#define ipc_share_in_start_1_1(phoneid, dst, size, arg, flags) \ |
ipc_share_in_start((phoneid), (dst), (size), (arg), (flags)) |
extern int ipc_share_in_start(int, void *, size_t, ipcarg_t, int *); |
extern int ipc_share_in_receive(ipc_callid_t *, size_t *); |
extern int ipc_share_in_finalize(ipc_callid_t, void *, int ); |
extern int ipc_share_out_start(int, void *, int); |
extern int ipc_share_out_receive(ipc_callid_t *, size_t *, int *); |
extern int ipc_share_out_finalize(ipc_callid_t, void *); |
extern int ipc_data_read_start(int, void *, size_t); |
extern int ipc_data_read_receive(ipc_callid_t *, size_t *); |
extern int ipc_data_read_finalize(ipc_callid_t, const void *, size_t); |
extern int ipc_data_write_start(int, const void *, size_t); |
extern int ipc_data_write_receive(ipc_callid_t *, size_t *); |
extern int ipc_data_write_finalize(ipc_callid_t, void *, size_t); |
extern int ipc_share_in_start(int phoneid, void *dst, size_t size, ipcarg_t arg, |
int *flags); |
extern int ipc_share_in_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_share_in_finalize(ipc_callid_t callid, void *src, int flags); |
extern int ipc_share_out_start(int phoneid, void *src, int flags); |
extern int ipc_share_out_receive(ipc_callid_t *callid, size_t *size, int *flags); |
extern int ipc_share_out_finalize(ipc_callid_t callid, void *dst); |
extern int ipc_data_read_start(int phoneid, void *dst, size_t size); |
extern int ipc_data_read_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size); |
extern int ipc_data_write_start(int phoneid, void *src, size_t size); |
extern int ipc_data_write_receive(ipc_callid_t *callid, size_t *size); |
extern int ipc_data_write_finalize(ipc_callid_t callid, void *dst, size_t size); |
#include <task.h> |
extern int ipc_connect_kbox(task_id_t); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/ipc/fb.h |
---|
48,11 → 48,10 |
FB_VIEWPORT_CREATE, |
FB_VIEWPORT_DELETE, |
FB_SET_STYLE, |
FB_SET_COLOR, |
FB_SET_RGB_COLOR, |
FB_GET_RESOLUTION, |
FB_DRAW_TEXT_DATA, |
FB_FLUSH, |
FB_VIEWPORT_DB, |
FB_DRAW_PPM, |
FB_PREPARE_SHM, |
FB_DROP_SHM, |
60,6 → 59,7 |
FB_VP_DRAW_PIXMAP, |
FB_VP2PIXMAP, |
FB_DROP_PIXMAP, |
FB_TRANS_PUTCHAR, |
FB_ANIM_CREATE, |
FB_ANIM_DROP, |
FB_ANIM_ADDPIXMAP, |
69,6 → 69,7 |
FB_POINTER_MOVE |
} fb_request_t; |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/ipc/services.h |
---|
30,8 → 30,8 |
* @{ |
*/ |
/** |
* @file services.h |
* @brief List of all known services and their codes. |
* @file services.h |
* @brief List of all known services and their codes. |
*/ |
#ifndef LIBIPC_SERVICES_H_ |
38,15 → 38,13 |
#define LIBIPC_SERVICES_H_ |
typedef enum { |
SERVICE_LOAD = 1, |
SERVICE_PCI, |
SERVICE_PCI = 1, |
SERVICE_KEYBOARD, |
SERVICE_VIDEO, |
SERVICE_CONSOLE, |
SERVICE_RD, |
SERVICE_VFS, |
SERVICE_DEVMAP, |
SERVICE_FHC, |
SERVICE_OBIO |
SERVICE_DEVMAP |
} services_t; |
/* Memory area to be received from NS */ |
/branches/dd/uspace/lib/libc/include/byteorder.h |
---|
52,14 → 52,6 |
#define uint32_t_be2host(n) (n) |
#define uint64_t_be2host(n) (n) |
#define host2uint16_t_le(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_le(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_le(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_be(n) (n) |
#define host2uint32_t_be(n) (n) |
#define host2uint64_t_be(n) (n) |
#else |
#define uint16_t_le2host(n) (n) |
70,14 → 62,6 |
#define uint32_t_be2host(n) uint32_t_byteorder_swap(n) |
#define uint64_t_be2host(n) uint64_t_byteorder_swap(n) |
#define host2uint16_t_le(n) (n) |
#define host2uint32_t_le(n) (n) |
#define host2uint64_t_le(n) (n) |
#define host2uint16_t_be(n) uint16_t_byteorder_swap(n) |
#define host2uint32_t_be(n) uint32_t_byteorder_swap(n) |
#define host2uint64_t_be(n) uint64_t_byteorder_swap(n) |
#endif |
static inline uint64_t uint64_t_byteorder_swap(uint64_t n) |
/branches/dd/uspace/lib/libc/include/unistd.h |
---|
44,11 → 44,9 |
#define getpagesize() (PAGE_SIZE) |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
extern ssize_t write(int, const void *, size_t); |
extern ssize_t read(int, void *, size_t); |
/branches/dd/uspace/lib/libc/include/stdio.h |
---|
49,65 → 49,27 |
int n; \ |
n = snprintf(buf, sizeof(buf), fmt, ##__VA_ARGS__); \ |
if (n > 0) \ |
(void) __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, strlen(buf)); \ |
(void) __SYSCALL3(SYS_IO, 1, (sysarg_t) buf, strlen(buf)); \ |
} |
typedef struct { |
/** Underlying file descriptor. */ |
int fd; |
extern int getchar(void); |
/** Error indicator. */ |
int error; |
extern int puts(const char * str); |
extern int putchar(int c); |
/** End-of-file indicator. */ |
int eof; |
} FILE; |
extern int printf(const char *fmt, ...); |
extern int sprintf(char *str, const char *fmt, ...); |
extern int snprintf(char *str, size_t size, const char *fmt, ...); |
extern FILE *stdin, *stdout, *stderr; |
extern int vprintf(const char *fmt, va_list ap); |
extern int vsprintf(char *str, const char *fmt, va_list ap); |
extern int vsnprintf(char *str, size_t size, const char *fmt, va_list ap); |
extern int getchar(void); |
#define fprintf(f, fmt, ...) printf(fmt, ##__VA_ARGS__) |
extern int puts(const char *); |
extern int putchar(int); |
extern int printf(const char *, ...); |
extern int asprintf(char **, const char *, ...); |
extern int sprintf(char *, const char *, ...); |
extern int snprintf(char *, size_t , const char *, ...); |
extern int vprintf(const char *, va_list); |
extern int vsprintf(char *, const char *, va_list); |
extern int vsnprintf(char *, size_t, const char *, va_list); |
extern int rename(const char *, const char *); |
extern FILE *fopen(const char *, const char *); |
extern int fclose(FILE *); |
extern size_t fread(void *, size_t, size_t, FILE *); |
extern size_t fwrite(const void *, size_t, size_t, FILE *); |
extern int feof(FILE *); |
extern int ferror(FILE *); |
extern void clearerr(FILE *); |
extern int fgetc(FILE *); |
extern int fputc(int, FILE *); |
extern int fputs(const char *, FILE *); |
extern int fprintf(FILE *, const char *, ...); |
extern int vfprintf(FILE *, const char *, va_list); |
#define getc fgetc |
#define putc fputc |
extern int fseek(FILE *, long, int); |
#ifndef SEEK_SET |
#define SEEK_SET 0 |
#define SEEK_CUR 1 |
#define SEEK_END 2 |
#endif |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/include/errno.h |
---|
35,10 → 35,6 |
#ifndef LIBC_ERRNO_H_ |
#define LIBC_ERRNO_H_ |
/* TODO: support threads/fibrils */ |
extern int _errno; |
#define errno _errno |
#include <kernel/errno.h> |
#define ENAMETOOLONG (-256) |
50,8 → 46,6 |
#define EBADF (-262) |
#define ERANGE (-263) |
#define EXDEV (-264) |
#define EIO (-265) |
#define EMLINK (-266) |
#endif |
/branches/dd/uspace/lib/libc/include/vfs/vfs.h |
---|
35,13 → 35,8 |
#ifndef LIBC_VFS_H_ |
#define LIBC_VFS_H_ |
#include <sys/types.h> |
extern int mount(const char *, const char *, const char *); |
extern char *absolutize(const char *, size_t *); |
extern int mount(const char *, const char *, const char *, |
const unsigned int flags); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/string.h |
---|
35,12 → 35,18 |
#ifndef LIBC_STRING_H_ |
#define LIBC_STRING_H_ |
#include <mem.h> |
#include <sys/types.h> |
#define bzero(ptr, len) memset((ptr), 0, (len)) |
extern void * memset(void *, int, size_t); |
extern void * memcpy(void *, const void *, size_t); |
extern void * memmove(void *, const void *, size_t); |
extern int bcmp(const char *, const char *, size_t); |
extern int strcmp(const char *, const char *); |
extern int strncmp(const char *, const char *, size_t); |
extern int stricmp(const char *, const char *); |
extern char *strcpy(char *, const char *); |
extern char *strncpy(char *, const char *, size_t); |
49,8 → 55,6 |
extern size_t strlen(const char *); |
extern char *strdup(const char *); |
extern char *strchr(const char *, int); |
extern char *strrchr(const char *, int); |
57,9 → 61,6 |
extern long int strtol(const char *, char **, int); |
extern unsigned long strtoul(const char *, char **, int); |
extern char * strtok_r(char *, const char *, char **); |
extern char * strtok(char *, const char *); |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/sys/types.h |
---|
42,10 → 42,6 |
typedef long off_t; |
typedef int mode_t; |
typedef volatile uint8_t ioport8_t; |
typedef volatile uint16_t ioport16_t; |
typedef volatile uint32_t ioport32_t; |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/io/stream.h |
---|
39,16 → 39,14 |
#define EMFILE -17 |
extern void open_console(void); |
extern void close_console(void); |
extern void klog_update(void); |
extern void open_stdin(void); |
extern void open_stdout(void); |
extern ssize_t read_stdin(void *, size_t); |
extern ssize_t write_stdout(const void *, size_t); |
extern ssize_t write_stderr(const void *, size_t); |
extern int get_console_phone(void); |
extern void console_wait(void); |
extern int get_cons_phone(void); |
#endif |
/branches/dd/uspace/lib/libc/include/async.h |
---|
76,7 → 76,7 |
#define async_send_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, dataptr) \ |
async_send_slow((phoneid), (method), (arg1), (arg2), (arg3), (arg4), \ |
(arg5), (dataptr)) |
extern aid_t async_send_fast(int phoneid, ipcarg_t method, ipcarg_t arg1, |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr); |
extern aid_t async_send_slow(int phoneid, ipcarg_t method, ipcarg_t arg1, |
86,8 → 86,8 |
extern int async_wait_timeout(aid_t amsgid, ipcarg_t *retval, |
suseconds_t timeout); |
fid_t async_new_connection(ipcarg_t in_phone_hash, ipc_callid_t callid, |
ipc_call_t *call, void (*cthread)(ipc_callid_t, ipc_call_t *)); |
fid_t async_new_connection(ipcarg_t in_phone_hash,ipc_callid_t callid, |
ipc_call_t *call, void (*cthread)(ipc_callid_t,ipc_call_t *)); |
void async_usleep(suseconds_t timeout); |
void async_create_manager(void); |
void async_destroy_manager(void); |
118,7 → 118,7 |
/* |
* User-friendly wrappers for async_req_fast() and async_req_slow(). The macros |
* are in the form async_req_m_n(), where m is the number of payload arguments |
* and n is the number of return arguments. The macros decide between the fast |
* and n is the number of return arguments. The macros decidce between the fast |
* and slow verion based on m. |
*/ |
#define async_req_0_0(phoneid, method) \ |
/branches/dd/uspace/lib/libc/include/syscall.h |
---|
32,28 → 32,15 |
/** |
* @file |
* @brief Syscall function declaration for architectures that don't |
* inline syscalls or architectures that handle syscalls |
* according to the number of arguments. |
* inline syscalls. |
*/ |
#ifndef LIBC_SYSCALL_H_ |
#define LIBC_SYSCALL_H_ |
#ifndef LIBARCH_SYSCALL_GENERIC |
#error "You can't include this file directly." |
#endif |
#include <sys/types.h> |
#include <kernel/syscall/syscall.h> |
#define __syscall0 __syscall |
#define __syscall1 __syscall |
#define __syscall2 __syscall |
#define __syscall3 __syscall |
#define __syscall4 __syscall |
#define __syscall5 __syscall |
#define __syscall6 __syscall |
extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2, |
const sysarg_t p3, const sysarg_t p4, const sysarg_t p5, const sysarg_t p6, |
const syscall_t id); |
/branches/dd/uspace/lib/libc/include/libc.h |
---|
39,22 → 39,17 |
#include <kernel/syscall/syscall.h> |
#include <libarch/syscall.h> |
#define __SYSCALL0(id) \ |
__syscall0(0, 0, 0, 0, 0, 0, id) |
#define __SYSCALL1(id, p1) \ |
__syscall1(p1, 0, 0, 0, 0, 0, id) |
#define __SYSCALL2(id, p1, p2) \ |
__syscall2(p1, p2, 0, 0, 0, 0, id) |
#define __SYSCALL3(id, p1, p2, p3) \ |
__syscall3(p1, p2, p3, 0, 0, 0, id) |
#define __SYSCALL4(id, p1, p2, p3, p4) \ |
__syscall4(p1, p2, p3, p4, 0, 0, id) |
#define __SYSCALL5(id, p1, p2, p3, p4, p5) \ |
__syscall5(p1, p2, p3, p4, p5, 0, id) |
#define __SYSCALL0(id) __syscall(0, 0, 0, 0, 0, 0, id) |
#define __SYSCALL1(id, p1) __syscall(p1, 0, 0, 0, 0, 0, id) |
#define __SYSCALL2(id, p1, p2) __syscall(p1, p2, 0, 0, 0, 0, id) |
#define __SYSCALL3(id, p1, p2, p3) __syscall(p1, p2, p3, 0, 0, 0, id) |
#define __SYSCALL4(id, p1, p2, p3, p4) __syscall(p1, p2, p3, p4, 0, 0, id) |
#define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall(p1, p2, p3, p4, p5, 0, id) |
#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \ |
__syscall6(p1, p2, p3, p4, p5, p6, id) |
__syscall(p1, p2, p3, p4, p5, p6,id) |
extern void __main(void *pcb_ptr); |
extern void __main(void); |
extern void __io_init(void); |
extern void __exit(void); |
#endif |
/branches/dd/uspace/lib/libc/include/as.h |
---|
42,7 → 42,6 |
extern void *as_area_create(void *address, size_t size, int flags); |
extern int as_area_resize(void *address, size_t size, int flags); |
extern int as_area_change_flags(void *address, int flags); |
extern int as_area_destroy(void *address); |
extern void *set_maxheapsize(size_t mhs); |
extern void * as_get_mappable_page(size_t sz); |
/branches/dd/uspace/lib/libc/include/task.h |
---|
40,8 → 40,6 |
typedef uint64_t task_id_t; |
extern task_id_t task_get_id(void); |
extern int task_set_name(const char *name); |
extern task_id_t task_spawn(const char *path, char *const argv[]); |
#endif |
/branches/dd/uspace/lib/libc/include/ctype.h |
---|
76,22 → 76,6 |
} |
} |
static inline int tolower(int c) |
{ |
if (isupper(c)) |
return (c + ('a' - 'A')); |
else |
return c; |
} |
static inline int toupper(int c) |
{ |
if (islower(c)) |
return (c + ('A' - 'a')); |
else |
return c; |
} |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/align.h |
---|
35,28 → 35,21 |
#ifndef LIBC_ALIGN_H_ |
#define LIBC_ALIGN_H_ |
/** Align to the nearest lower address which is a power of two. |
/** Align to the nearest lower address. |
* |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_DOWN(s, a) ((s) & ~((a) - 1)) |
/** Align to the nearest higher address which is a power of two. |
/** Align to the nearest higher address. |
* |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
* @param s Address or size to be aligned. |
* @param a Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(s, a) ((long)((s) + ((a) - 1)) & ~((long) (a) - 1)) |
/** Round up to the nearest higher boundary. |
* |
* @param n Number to be aligned. |
* @param b Boundary, arbitrary unsigned number. |
*/ |
#define ROUND_UP(n, b) (((n) / (b) + ((n) % (b) != 0)) * (b)) |
#endif |
/** @} |
/branches/dd/uspace/lib/libc/include/ddi.h |
---|
37,10 → 37,9 |
#include <task.h> |
extern int physmem_map(void *, void *, unsigned long, int); |
extern int iospace_enable(task_id_t, void *, unsigned long); |
extern int preemption_control(int); |
extern int pio_enable(void *, size_t, void **); |
extern int physmem_map(void *pf, void *vp, unsigned long pages, int flags); |
extern int iospace_enable(task_id_t id, void *ioaddr, unsigned long size); |
extern int preemption_control(int enable); |
#endif |
/branches/dd/uspace/lib/libc/generic/kbd.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/pcb.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/mem.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/uspace/lib/libc/generic/smc.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/getopt.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/udebug.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/loader.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/console.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/ipc.c |
---|
598,7 → 598,7 |
ipcarg_t newphid; |
int res; |
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
res = ipc_call_sync_3_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
NULL, NULL, NULL, NULL, &newphid); |
if (res) |
return res; |
605,30 → 605,6 |
return newphid; |
} |
/** Ask through phone for a new connection to some service. |
* |
* If the connection is not available at the moment, the |
* call will block. |
* |
* @param phoneid Phone handle used for contacting the other side. |
* @param arg1 User defined argument. |
* @param arg2 User defined argument. |
* @param arg3 User defined argument. |
* |
* @return New phone handle on success or a negative error code. |
*/ |
int ipc_connect_me_to_blocking(int phoneid, int arg1, int arg2, int arg3) |
{ |
ipcarg_t newphid; |
int res; |
res = ipc_call_sync_4_5(phoneid, IPC_M_CONNECT_ME_TO, arg1, arg2, arg3, |
IPC_FLAG_BLOCKING, NULL, NULL, NULL, NULL, &newphid); |
if (res) |
return res; |
return newphid; |
} |
/** Hang up a phone. |
* |
* @param phoneid Handle of the phone to be hung up. |
690,23 → 666,6 |
arg2, mode); |
} |
int ipc_forward_slow(ipc_callid_t callid, int phoneid, int method, |
ipcarg_t arg1, ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipcarg_t arg5, |
int mode) |
{ |
ipc_call_t data; |
IPC_SET_METHOD(data, method); |
IPC_SET_ARG1(data, arg1); |
IPC_SET_ARG2(data, arg2); |
IPC_SET_ARG3(data, arg3); |
IPC_SET_ARG4(data, arg4); |
IPC_SET_ARG5(data, arg5); |
return __SYSCALL3(SYS_IPC_FORWARD_SLOW, callid, (sysarg_t) &data, mode); |
} |
/** Wrapper for making IPC_M_SHARE_IN calls. |
* |
* @param phoneid Phone that will be used to contact the receiving side. |
723,7 → 682,7 |
{ |
int res; |
sysarg_t tmp_flags; |
res = async_req_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
res = ipc_call_sync_3_2(phoneid, IPC_M_SHARE_IN, (ipcarg_t) dst, |
(ipcarg_t) size, arg, NULL, &tmp_flags); |
if (flags) |
*flags = tmp_flags; |
783,7 → 742,7 |
*/ |
int ipc_share_out_start(int phoneid, void *src, int flags) |
{ |
return async_req_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
return ipc_call_sync_3_0(phoneid, IPC_M_SHARE_OUT, (ipcarg_t) src, 0, |
(ipcarg_t) flags); |
} |
844,7 → 803,7 |
*/ |
int ipc_data_read_start(int phoneid, void *dst, size_t size) |
{ |
return async_req_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_READ, (ipcarg_t) dst, |
(ipcarg_t) size); |
} |
888,7 → 847,7 |
* |
* @return Zero on success or a value from @ref errno.h on failure. |
*/ |
int ipc_data_read_finalize(ipc_callid_t callid, const void *src, size_t size) |
int ipc_data_read_finalize(ipc_callid_t callid, void *src, size_t size) |
{ |
return ipc_answer_2(callid, EOK, (ipcarg_t) src, (ipcarg_t) size); |
} |
901,9 → 860,9 |
* |
* @return Zero on success or a negative error code from errno.h. |
*/ |
int ipc_data_write_start(int phoneid, const void *src, size_t size) |
int ipc_data_write_start(int phoneid, void *src, size_t size) |
{ |
return async_req_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
return ipc_call_sync_2_0(phoneid, IPC_M_DATA_WRITE, (ipcarg_t) src, |
(ipcarg_t) size); |
} |
950,18 → 909,6 |
{ |
return ipc_answer_2(callid, EOK, (ipcarg_t) dst, (ipcarg_t) size); |
} |
#include <kernel/syscall/sysarg64.h> |
/** Connect to a task specified by id. |
*/ |
int ipc_connect_kbox(task_id_t id) |
{ |
sysarg64_t arg; |
arg.value = (unsigned long long) id; |
return __SYSCALL1(SYS_IPC_CONNECT_KBOX, (sysarg_t) &arg); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/vfs/vfs.c |
---|
31,7 → 31,7 |
*/ |
/** @file |
*/ |
#include <vfs/vfs.h> |
#include <vfs/canonify.h> |
#include <stdlib.h> |
48,8 → 48,7 |
#include <futex.h> |
#include <errno.h> |
#include <string.h> |
#include <ipc/devmap.h> |
#include "../../../srv/vfs/vfs.h" |
#include "../../srv/vfs/vfs.h" |
int vfs_phone = -1; |
futex_t vfs_phone_futex = FUTEX_INITIALIZER; |
57,12 → 56,11 |
futex_t cwd_futex = FUTEX_INITIALIZER; |
DIR *cwd_dir = NULL; |
char *cwd_path = NULL; |
size_t cwd_len = 0; |
size_t cwd_len = 0; |
char *absolutize(const char *path, size_t *retlen) |
static char *absolutize(const char *path, size_t *retlen) |
{ |
char *ncwd_path; |
char *ncwd_path_nc; |
futex_down(&cwd_futex); |
size_t len = strlen(path); |
71,112 → 69,65 |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path_nc = malloc(cwd_len + 1 + len + 1); |
if (!ncwd_path_nc) { |
ncwd_path = malloc(len + cwd_len + 1); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
strcpy(ncwd_path_nc, cwd_path); |
ncwd_path_nc[cwd_len] = '/'; |
ncwd_path_nc[cwd_len + 1] = '\0'; |
strcpy(ncwd_path, cwd_path); |
ncwd_path[cwd_len] = '/'; |
ncwd_path[cwd_len + 1] = '\0'; |
} else { |
ncwd_path_nc = malloc(len + 1); |
if (!ncwd_path_nc) { |
ncwd_path = malloc(len + 1); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
ncwd_path_nc[0] = '\0'; |
ncwd_path[0] = '\0'; |
} |
strcat(ncwd_path_nc, path); |
ncwd_path = canonify(ncwd_path_nc, retlen); |
if (!ncwd_path) { |
strcat(ncwd_path, path); |
if (!canonify(ncwd_path, retlen)) { |
futex_up(&cwd_futex); |
free(ncwd_path_nc); |
free(ncwd_path); |
return NULL; |
} |
/* |
* We need to clone ncwd_path because canonify() works in-place and thus |
* the address in ncwd_path need not be the same as ncwd_path_nc, even |
* though they both point into the same dynamically allocated buffer. |
*/ |
ncwd_path = strdup(ncwd_path); |
free(ncwd_path_nc); |
if (!ncwd_path) { |
futex_up(&cwd_futex); |
return NULL; |
} |
futex_up(&cwd_futex); |
return ncwd_path; |
} |
static void vfs_connect(void) |
static int vfs_connect(void) |
{ |
while (vfs_phone < 0) |
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); |
if (vfs_phone < 0) |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
return vfs_phone; |
} |
static int device_get_handle(const char *name, dev_handle_t *handle, |
const unsigned int flags) |
int mount(const char *fs_name, const char *mp, const char *dev) |
{ |
int phone; |
if (flags & IPC_FLAG_BLOCKING) |
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
else |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_CLIENT, 0); |
if (phone < 0) |
return phone; |
ipc_call_t answer; |
aid_t req = async_send_2(phone, DEVMAP_DEVICE_GET_HANDLE, flags, 0, |
&answer); |
ipcarg_t retval = ipc_data_write_start(phone, name, strlen(name) + 1); |
if (retval != EOK) { |
async_wait_for(req, NULL); |
ipc_hangup(phone); |
return retval; |
} |
async_wait_for(req, &retval); |
if (handle != NULL) |
*handle = -1; |
if (retval == EOK) { |
if (handle != NULL) |
*handle = (dev_handle_t) IPC_GET_ARG1(answer); |
} |
ipc_hangup(phone); |
return retval; |
} |
int mount(const char *fs_name, const char *mp, const char *dev, |
const unsigned int flags) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
dev_handle_t dev_handle; |
res = device_get_handle(dev, &dev_handle, flags); |
if (res != EOK) |
return res; |
dev_handle_t dev_handle = 0; /* TODO */ |
size_t mpa_len; |
char *mpa = absolutize(mp, &mpa_len); |
if (!mpa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
req = async_send_2(vfs_phone, VFS_MOUNT, dev_handle, flags, NULL); |
rc = ipc_data_write_start(vfs_phone, (void *) mpa, mpa_len); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_MOUNT, dev_handle, NULL); |
rc = ipc_data_write_start(vfs_phone, (void *)fs_name, strlen(fs_name)); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
184,8 → 135,7 |
free(mpa); |
return (int) rc; |
} |
rc = ipc_data_write_start(vfs_phone, (void *) fs_name, strlen(fs_name)); |
rc = ipc_data_write_start(vfs_phone, (void *)mpa, mpa_len); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
async_serialize_end(); |
193,17 → 143,16 |
free(mpa); |
return (int) rc; |
} |
async_wait_for(req, &rc); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(mpa); |
return (int) rc; |
} |
static int _open(const char *path, int lflag, int oflag, ...) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
215,8 → 164,15 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_3(vfs_phone, VFS_OPEN, lflag, oflag, 0, &answer); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
230,9 → 186,6 |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
if (rc != EOK) |
return (int) rc; |
return (int) IPC_GET_ARG1(answer); |
} |
243,14 → 196,22 |
int close(int fildes) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
rc = async_req_1_0(vfs_phone, VFS_CLOSE, fildes); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
259,6 → 220,7 |
ssize_t read(int fildes, void *buf, size_t nbyte) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
265,8 → 227,14 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_READ, fildes, &answer); |
rc = ipc_data_read_start(vfs_phone, (void *)buf, nbyte); |
if (rc != EOK) { |
281,11 → 249,12 |
if (rc == EOK) |
return (ssize_t) IPC_GET_ARG1(answer); |
else |
return rc; |
return -1; |
} |
ssize_t write(int fildes, const void *buf, size_t nbyte) |
{ |
int res; |
ipcarg_t rc; |
ipc_call_t answer; |
aid_t req; |
292,8 → 261,14 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_WRITE, fildes, &answer); |
rc = ipc_data_write_start(vfs_phone, (void *)buf, nbyte); |
if (rc != EOK) { |
313,15 → 288,23 |
off_t lseek(int fildes, off_t offset, int whence) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
ipcarg_t newoffs; |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
off_t newoffs; |
rc = async_req_3_1(vfs_phone, VFS_SEEK, fildes, offset, whence, |
&newoffs); |
(ipcarg_t)&newoffs); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
329,17 → 312,24 |
if (rc != EOK) |
return (off_t) -1; |
return (off_t) newoffs; |
return newoffs; |
} |
int ftruncate(int fildes, off_t length) |
{ |
int res; |
ipcarg_t rc; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
return res; |
} |
} |
rc = async_req_2_0(vfs_phone, VFS_TRUNCATE, fildes, length); |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
381,6 → 371,7 |
int mkdir(const char *path, mode_t mode) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
388,11 → 379,18 |
char *pa = absolutize(path, &pa_len); |
if (!pa) |
return ENOMEM; |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_1(vfs_phone, VFS_MKDIR, mode, NULL); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
411,6 → 409,7 |
static int _unlink(const char *path, int lflag) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
421,8 → 420,15 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(pa); |
return res; |
} |
} |
req = async_send_0(vfs_phone, VFS_UNLINK, NULL); |
rc = ipc_data_write_start(vfs_phone, pa, pa_len); |
if (rc != EOK) { |
451,6 → 457,7 |
int rename(const char *old, const char *new) |
{ |
int res; |
ipcarg_t rc; |
aid_t req; |
468,8 → 475,16 |
futex_down(&vfs_phone_futex); |
async_serialize_start(); |
vfs_connect(); |
if (vfs_phone < 0) { |
res = vfs_connect(); |
if (res < 0) { |
async_serialize_end(); |
futex_up(&vfs_phone_futex); |
free(olda); |
free(newa); |
return res; |
} |
} |
req = async_send_0(vfs_phone, VFS_RENAME, NULL); |
rc = ipc_data_write_start(vfs_phone, olda, olda_len); |
if (rc != EOK) { |
522,7 → 537,6 |
cwd_path = pa; |
cwd_len = pa_len; |
futex_up(&cwd_futex); |
return EOK; |
} |
char *getcwd(char *buf, size_t size) |
/branches/dd/uspace/lib/libc/generic/vfs/canonify.c |
---|
36,7 → 36,6 |
*/ |
#include <stdlib.h> |
#include <vfs/canonify.h> |
/** Token types used for tokenization of path. */ |
typedef enum { |
126,7 → 125,6 |
static void set_first_slash(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
*tfsl = *t; |
*tlcomp = *t; |
} |
static void save_component(token_t *t, token_t *tfsl, token_t *tlcomp) |
{ |
/branches/dd/uspace/lib/libc/generic/string.c |
---|
1,6 → 1,5 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
34,16 → 33,96 |
*/ |
#include <string.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <ctype.h> |
#include <limits.h> |
#include <ctype.h> |
#include <malloc.h> |
#include <align.h> |
#include <sys/types.h> |
/** Count the number of characters in the string, not including terminating 0. |
/* Dummy implementation of mem/ functions */ |
void *memset(void *s, int c, size_t n) |
{ |
char *os = s; |
while (n--) |
*(os++) = c; |
return s; |
} |
struct along { |
unsigned long n; |
} __attribute__ ((packed)); |
static void *unaligned_memcpy(void *dst, const void *src, size_t n) |
{ |
int i, j; |
struct along *adst = dst; |
const struct along *asrc = src; |
for (i = 0; i < n / sizeof(unsigned long); i++) |
adst[i].n = asrc[i].n; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
} |
void *memcpy(void *dst, const void *src, size_t n) |
{ |
int i, j; |
if (((long) dst & (sizeof(long) - 1)) || ((long) src & (sizeof(long) - 1))) |
return unaligned_memcpy(dst, src, n); |
for (i = 0; i < n / sizeof(unsigned long); i++) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
for (j = 0; j < n % sizeof(unsigned long); j++) |
((unsigned char *) (((unsigned long *) dst) + i))[j] = ((unsigned char *) (((unsigned long *) src) + i))[j]; |
return (char *) src; |
} |
void *memmove(void *dst, const void *src, size_t n) |
{ |
int i, j; |
if (src > dst) |
return memcpy(dst, src, n); |
for (j = (n % sizeof(unsigned long)) - 1; j >= 0; j--) |
((unsigned char *) ((unsigned long *) dst))[j] = ((unsigned char *) ((unsigned long *) src))[j]; |
for (i = n / sizeof(unsigned long) - 1; i >=0 ; i--) |
((unsigned long *) dst)[i] = ((unsigned long *) src)[i]; |
return (char *) src; |
} |
/** Compare two memory areas. |
* |
* @param str String. |
* @return Number of characters in string. |
* @param s1 Pointer to the first area to compare. |
* @param s2 Pointer to the second area to compare. |
* @param len Size of the first area in bytes. Both areas must have the same |
* length. |
* @return If len is 0, return zero. If the areas match, return zero. |
* Otherwise return non-zero. |
*/ |
int bcmp(const char *s1, const char *s2, size_t len) |
{ |
for (; len && *s1++ == *s2++; len--) |
; |
return len; |
} |
/** Count the number of characters in the string, not including terminating 0. |
* @param str string |
* @return number of characters in string. |
*/ |
size_t strlen(const char *str) |
{ |
size_t counter = 0; |
62,6 → 141,7 |
c++; |
return (a[c] - b[c]); |
} |
int strncmp(const char *a, const char *b, size_t n) |
75,22 → 155,10 |
} |
int stricmp(const char *a, const char *b) |
{ |
int c = 0; |
while (a[c] && b[c] && (!(tolower(a[c]) - tolower(b[c])))) |
c++; |
return (tolower(a[c]) - tolower(b[c])); |
} |
/** Return pointer to the first occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
/** Return pointer to the first occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
*/ |
char *strchr(const char *str, int c) |
{ |
103,12 → 171,10 |
return NULL; |
} |
/** Return pointer to the last occurence of character c in string. |
* |
* @param str Scanned string. |
* @param c Searched character (taken as one byte). |
* @return Pointer to the matched character or NULL if it is not |
* found in given string. |
/** Return pointer to the last occurence of character c in string |
* @param str scanned string |
* @param c searched character (taken as one byte) |
* @return pointer to the matched character or NULL if it is not found in given string. |
*/ |
char *strrchr(const char *str, int c) |
{ |
125,16 → 191,13 |
/** Convert string to a number. |
* Core of strtol and strtoul functions. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @param sgn It's set to 1 if minus found. |
* @return Result of conversion. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @param sgn its set to 1 if minus found |
* @return result of conversion. |
*/ |
static unsigned long |
_strtoul(const char *nptr, char **endptr, int base, char *sgn) |
static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn) |
{ |
unsigned char c; |
unsigned long result = 0; |
156,8 → 219,7 |
/* FIXME: set errno to EINVAL */ |
return 0; |
} |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || |
(str[1] == 'X'))) { |
if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) { |
str += 2; |
} |
} else { |
176,8 → 238,7 |
while (*str) { |
c = *str; |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : |
(c <= '9' ? c - '0' : 0xff))); |
c = (c >= 'a' ? c - 'a' + 10 : (c >= 'A' ? c - 'A' + 10 : (c <= '9' ? c - '0' : 0xff))); |
if (c > base) { |
break; |
} |
196,10 → 257,7 |
} |
if (str == tmpptr) { |
/* |
* No number was found => first invalid character is the first |
* character of the string. |
*/ |
/* no number was found => first invalid character is the first character of the string */ |
/* FIXME: set errno to EINVAL */ |
str = nptr; |
result = 0; |
217,17 → 275,14 |
} |
/** Convert initial part of string to long int according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character. |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
*/ |
long int strtol(const char *nptr, char **endptr, int base) |
{ |
250,17 → 305,14 |
/** Convert initial part of string to unsigned long according to given base. |
* The number may begin with an arbitrary number of whitespaces followed by |
* optional sign (`+' or `-'). If the base is 0 or 16, the prefix `0x' may be |
* inserted and the number will be taken as hexadecimal one. If the base is 0 |
* and the number begin with a zero, number will be taken as octal one (as with |
* base 8). Otherwise the base 0 is taken as decimal. |
* |
* @param nptr Pointer to string. |
* @param endptr If not NULL, function stores here pointer to the first |
* invalid character |
* @param base Zero or number between 2 and 36 inclusive. |
* @return Result of conversion. |
* The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-'). |
* If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one. |
* If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8). |
* Otherwise the base 0 is taken as decimal. |
* @param nptr pointer to string |
* @param endptr if not NULL, function stores here pointer to the first invalid character |
* @param base zero or number between 2 and 36 inclusive |
* @return result of conversion. |
*/ |
unsigned long strtoul(const char *nptr, char **endptr, int base) |
{ |
301,48 → 353,5 |
return orig; |
} |
char * strdup(const char *s1) |
{ |
size_t len = strlen(s1) + 1; |
void *ret = malloc(len); |
if (ret == NULL) |
return (char *) NULL; |
return (char *) memcpy(ret, s1, len); |
} |
char *strtok(char *s, const char *delim) |
{ |
static char *next; |
return strtok_r(s, delim, &next); |
} |
char *strtok_r(char *s, const char *delim, char **next) |
{ |
char *start, *end; |
if (s == NULL) |
s = *next; |
/* Skip over leading delimiters. */ |
while (*s && (strchr(delim, *s) != NULL)) ++s; |
start = s; |
/* Skip over token characters. */ |
while (*s && (strchr(delim, *s) == NULL)) ++s; |
end = s; |
*next = (*s ? s + 1 : s); |
if (start == end) { |
return NULL; /* No more tokens. */ |
} |
/* Overwrite delimiter with NULL terminator. */ |
*end = '\0'; |
return start; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/time.c |
---|
47,8 → 47,6 |
#include <as.h> |
#include <ddi.h> |
#include <time.h> |
/* Pointers to public variables with time */ |
struct { |
volatile sysarg_t seconds1; |
/branches/dd/uspace/lib/libc/generic/libc.c |
---|
48,41 → 48,28 |
#include <ipc/ipc.h> |
#include <async.h> |
#include <as.h> |
#include <loader/pcb.h> |
extern char _heap; |
extern int main(int argc, char *argv[]); |
int _errno; |
void _exit(int status) |
{ |
thread_exit(status); |
} |
void __main(void *pcb_ptr) |
void __main(void) |
{ |
fibril_t *f; |
int argc; |
char **argv; |
(void) as_area_create(&_heap, 1, AS_AREA_WRITE | AS_AREA_READ); |
_async_init(); |
f = fibril_setup(); |
__tcb_set(f->tcb); |
/* Save the PCB pointer */ |
__pcb = (pcb_t *)pcb_ptr; |
} |
if (__pcb == NULL) { |
argc = 0; |
argv = NULL; |
} else { |
argc = __pcb->argc; |
argv = __pcb->argv; |
} |
main(argc, argv); |
void __io_init(void) |
{ |
open_stdin(); |
open_stdout(); |
} |
void __exit(void) |
/branches/dd/uspace/lib/libc/generic/io/fprintf.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/stdio.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/asprintf.c |
---|
File deleted |
/branches/dd/uspace/lib/libc/generic/io/stream.c |
---|
42,8 → 42,7 |
#include <ipc/ns.h> |
#include <ipc/fb.h> |
#include <ipc/services.h> |
#include <ipc/console.h> |
#include <kbd/kbd.h> |
#include <console.h> |
#include <unistd.h> |
#include <async.h> |
#include <sys/types.h> |
57,77 → 56,54 |
ssize_t read_stdin(void *buf, size_t count) |
{ |
open_console(); |
if (console_phone >= 0) { |
kbd_event_t ev; |
int rc; |
size_t i = 0; |
while (i < count) { |
do { |
rc = kbd_get_event(&ev); |
if (rc < 0) return -1; |
} while (ev.c == 0 || ev.type == KE_RELEASE); |
ipcarg_t r0, r1; |
size_t i = 0; |
((char *) buf)[i++] = ev.c; |
while (i < count) { |
if (async_req_0_2(console_phone, CONSOLE_GETCHAR, &r0, |
&r1) < 0) { |
return -1; |
} |
return i; |
} else { |
return -1; |
((char *) buf)[i++] = r0; |
} |
return i; |
} |
ssize_t write_stdout(const void *buf, size_t count) |
{ |
open_console(); |
if (console_phone >= 0) { |
int i; |
int i; |
for (i = 0; i < count; i++) |
async_msg_1(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
for (i = 0; i < count; i++) |
async_msg_1(console_phone, CONSOLE_PUTCHAR, |
((const char *) buf)[i]); |
return count; |
} else |
return __SYSCALL3(SYS_KLOG, 1, (sysarg_t) buf, count); |
return count; |
} |
void open_console(void) |
void open_stdin(void) |
{ |
if (console_phone < 0) { |
int phone = ipc_connect_me_to(PHONE_NS, SERVICE_CONSOLE, 0, 0); |
if (phone >= 0) |
console_phone = phone; |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
usleep(10000); |
} |
} |
} |
void close_console(void) |
void open_stdout(void) |
{ |
if (console_phone >= 0) { |
if (ipc_hangup(console_phone) == 0) { |
console_phone = -1; |
if (console_phone < 0) { |
while ((console_phone = ipc_connect_me_to(PHONE_NS, |
SERVICE_CONSOLE, 0, 0)) < 0) { |
usleep(10000); |
} |
} |
} |
void klog_update(void) |
int get_cons_phone(void) |
{ |
(void) __SYSCALL3(SYS_KLOG, 1, NULL, 0); |
} |
int get_console_phone(void) |
{ |
if (console_phone < 0) |
console_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_CONSOLE, 0, 0); |
return console_phone; |
} |
void console_wait(void) |
{ |
while (console_phone < 0) |
get_console_phone(); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/io/printf_core.c |
---|
94,9 → 94,12 |
if (str == NULL) |
return printf_putnchars("(NULL)", 6, ps); |
count = strlen(str); |
for (count = 0; str[count] != 0; count++); |
return ps->write((void *) str, count, ps->data); |
if (ps->write((void *) str, count, ps->data) == count) |
return 0; |
return EOF; |
} |
/** Print one character to output |
/branches/dd/uspace/lib/libc/generic/io/vsnprintf.c |
---|
38,27 → 38,22 |
#include <io/printf_core.h> |
struct vsnprintf_data { |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
size_t size; /* total space for string */ |
size_t len; /* count of currently used characters */ |
char *string; /* destination string */ |
}; |
/** Write string to given buffer. |
* Write at most data->size characters including trailing zero. According to C99 |
* has snprintf to return number of characters that would have been written if |
* enough space had been available. Hence the return value is not number of |
* really printed characters but size of input string. Number of really used |
* characters is stored in data->len. |
* |
* @param str Source string to print. |
* @param count Size of the source string. |
* @param data Structure with destination string, counter of used space |
* and total string size. |
* @return Number of characters to print (not characters really |
* printed!) |
* Write at most data->size characters including trailing zero. According to C99 has snprintf to return number |
* of characters that would have been written if enough space had been available. Hence the return value is not |
* number of really printed characters but size of input string. Number of really used characters |
* is stored in data->len. |
* @param str source string to print |
* @param count size of source string |
* @param data structure with destination string, counter of used space and total string size. |
* @return number of characters to print (not characters really printed!) |
*/ |
static int |
vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
static int vsnprintf_write(const char *str, size_t count, struct vsnprintf_data *data) |
{ |
size_t i; |
i = data->size - data->len; |
68,10 → 63,7 |
} |
if (i == 1) { |
/* |
* We have only one free byte left in buffer => write there |
* trailing zero. |
*/ |
/* We have only one free byte left in buffer => write there trailing zero */ |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
78,23 → 70,17 |
} |
if (i <= count) { |
/* |
* We have not enought space for whole string with the trailing |
* zero => print only a part of string. |
*/ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
/* We have not enought space for whole string with the trailing zero => print only a part of string */ |
memcpy((void *)(data->string + data->len), (void *)str, i - 1); |
data->string[data->size - 1] = 0; |
data->len = data->size; |
return count; |
} |
/* Buffer is big enought to print whole string */ |
memcpy((void *)(data->string + data->len), (void *)str, count); |
data->len += count; |
/* |
* Put trailing zero at end, but not count it into data->len so it could |
* be rewritten next time. |
*/ |
/* Put trailing zero at end, but not count it into data->len so it could be rewritten next time */ |
data->string[data->len] = 0; |
return count; |
101,22 → 87,17 |
} |
/** Print formatted to the given buffer with limited size. |
* @param str Buffer. |
* @param size Bffer size. |
* @param fmt Format string. |
* @param str buffer |
* @param size buffer size |
* @param fmt format string |
* \see For more details about format string see printf_core. |
*/ |
int vsnprintf(char *str, size_t size, const char *fmt, va_list ap) |
{ |
struct vsnprintf_data data = {size, 0, str}; |
struct printf_spec ps = { |
(int(*)(void *, size_t, void *)) vsnprintf_write, |
&data |
}; |
struct printf_spec ps = {(int(*)(void *, size_t, void *)) vsnprintf_write, &data}; |
/* |
* Print 0 at end of string - fix the case that nothing will be printed. |
*/ |
/* Print 0 at end of string - fix the case that nothing will be printed */ |
if (size > 0) |
str[0] = 0; |
/branches/dd/uspace/lib/libc/generic/io/sprintf.c |
---|
48,6 → 48,7 |
va_start(args, fmt); |
ret = vsprintf(str, fmt, args); |
va_end(args); |
return ret; |
/branches/dd/uspace/lib/libc/generic/async.c |
---|
483,7 → 483,7 |
{ |
connection_t *conn; |
unsigned long key; |
conn = malloc(sizeof(*conn)); |
if (!conn) { |
if (callid) |
498,7 → 498,7 |
conn->call = *call; |
conn->wdata.active = 1; /* We will activate the fibril ASAP */ |
conn->cfibril = cfibril; |
conn->wdata.fid = fibril_create(connection_fibril, conn); |
if (!conn->wdata.fid) { |
free(conn); |
506,15 → 506,14 |
ipc_answer_0(callid, ENOMEM); |
return NULL; |
} |
/* Add connection to the connection hash table */ |
key = conn->in_phone_hash; |
futex_down(&async_futex); |
hash_table_insert(&conn_hash_table, &key, &conn->link); |
futex_up(&async_futex); |
fibril_add_ready(conn->wdata.fid); |
return conn->wdata.fid; |
} |
525,7 → 524,6 |
* |
* @param callid Hash of the incoming call. |
* @param call Data of the incoming call. |
* |
*/ |
static void handle_call(ipc_callid_t callid, ipc_call_t *call) |
{ |
535,8 → 533,8 |
(*interrupt_received)(callid, call); |
_in_interrupt_handler = 0; |
return; |
} |
} |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_CONNECT_ME_TO: |
/* Open new connection with fibril etc. */ |
544,11 → 542,11 |
client_connection); |
return; |
} |
/* Try to route the call through the connection hash table */ |
if (route_call(callid, call)) |
return; |
/* Unknown call from unknown phone - hang it up */ |
ipc_answer_0(callid, EHANGUP); |
} |
741,17 → 739,23 |
ipcarg_t arg2, ipcarg_t arg3, ipcarg_t arg4, ipc_call_t *dataptr) |
{ |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot send asynchronous request in interrupt " |
"handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
msg->done = 0; |
msg->dataptr = dataptr; |
/* We may sleep in the next method, but it will use its own mechanism */ |
msg->wdata.active = 1; |
ipc_call_async_4(phoneid, method, arg1, arg2, arg3, arg4, msg, |
reply_received, !_in_interrupt_handler); |
reply_received, 1); |
return (aid_t) msg; |
} |
777,17 → 781,23 |
ipc_call_t *dataptr) |
{ |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot send asynchronous request in interrupt " |
"handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
msg->done = 0; |
msg->dataptr = dataptr; |
/* We may sleep in next method, but it will use its own mechanism */ |
msg->wdata.active = 1; |
ipc_call_async_5(phoneid, method, arg1, arg2, arg3, arg4, arg5, msg, |
reply_received, !_in_interrupt_handler); |
reply_received, 1); |
return (aid_t) msg; |
} |
874,16 → 884,21 |
{ |
amsg_t *msg; |
if (_in_interrupt_handler) { |
printf("Cannot call async_usleep in interrupt handler.\n"); |
_exit(1); |
} |
msg = malloc(sizeof(*msg)); |
if (!msg) |
return; |
msg->wdata.fid = fibril_get_id(); |
msg->wdata.active = 0; |
gettimeofday(&msg->wdata.expires, NULL); |
tv_add(&msg->wdata.expires, timeout); |
futex_down(&async_futex); |
insert_timeout(&msg->wdata); |
/* Leave the async_futex locked when entering this function */ |
997,3 → 1012,4 |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/tls.c |
---|
116,7 → 116,7 |
tcb_t *tcb; |
size = ALIGN_UP(size, &_tls_alignment); |
*data = memalign((uintptr_t) &_tls_alignment, sizeof(tcb_t) + size); |
*data = memalign(&_tls_alignment, sizeof(tcb_t) + size); |
tcb = (tcb_t *) (*data + size); |
tcb->self = tcb; |
/branches/dd/uspace/lib/libc/generic/fibril.c |
---|
342,3 → 342,4 |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/thread.c |
---|
108,8 → 108,8 |
uarg->uspace_thread_arg = arg; |
uarg->uspace_uarg = uarg; |
rc = __SYSCALL4(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name, |
(sysarg_t) strlen(name), (sysarg_t) tid); |
rc = __SYSCALL3(SYS_THREAD_CREATE, (sysarg_t) uarg, (sysarg_t) name, |
(sysarg_t) tid); |
if (rc) { |
/* |
/branches/dd/uspace/lib/libc/generic/as.c |
---|
85,20 → 85,6 |
return __SYSCALL1(SYS_AS_AREA_DESTROY, (sysarg_t ) address); |
} |
/** Change address-space area flags. |
* |
* @param address Virtual address pointing into the address space area being |
* modified. |
* @param flags New flags describing type of the area. |
* |
* @return Zero on success or a code from @ref errno.h on failure. |
*/ |
int as_area_change_flags(void *address, int flags) |
{ |
return __SYSCALL2(SYS_AS_AREA_CHANGE_FLAGS, (sysarg_t) address, |
(sysarg_t) flags); |
} |
static size_t heapsize = 0; |
static size_t maxheapsize = (size_t) (-1); |
/branches/dd/uspace/lib/libc/generic/ddi.c |
---|
33,12 → 33,8 |
*/ |
#include <ddi.h> |
#include <libarch/ddi.h> |
#include <libc.h> |
#include <task.h> |
#include <as.h> |
#include <align.h> |
#include <libarch/config.h> |
#include <kernel/ddi/ddi_arg.h> |
/** Map piece of physical memory to task. |
45,20 → 41,18 |
* |
* Caller of this function must have the CAP_MEM_MANAGER capability. |
* |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the starting page. |
* @param pages Number of pages to map. |
* @param flags Flags for the new address space area. |
* @param pf Physical address of the starting frame. |
* @param vp Virtual address of the sterting page. |
* @param pages Number of pages to map. |
* @param flags Flags for the new address space area. |
* |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_MEM_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in creating address space area. |
* @return 0 on success, EPERM if the caller lacks the CAP_MEM_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in creating address space area. |
*/ |
int physmem_map(void *pf, void *vp, unsigned long pages, int flags) |
{ |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, |
flags); |
return __SYSCALL4(SYS_PHYSMEM_MAP, (sysarg_t) pf, (sysarg_t) vp, pages, flags); |
} |
/** Enable I/O space range to task. |
65,14 → 59,13 |
* |
* Caller of this function must have the IO_MEM_MANAGER capability. |
* |
* @param id Task ID. |
* @param ioaddr Starting address of the I/O range. |
* @param size Size of the range. |
* @param id Task ID. |
* @param ioaddr Starting address of the I/O range. |
* @param size Size of the range. |
* |
* @return 0 on success, EPERM if the caller lacks the |
* CAP_IO_MANAGER capability, ENOENT if there is no task |
* with specified ID and ENOMEM if there was some problem |
* in allocating memory. |
* @return 0 on success, EPERM if the caller lacks the CAP_IO_MANAGER capability, |
* ENOENT if there is no task with specified ID and ENOMEM if there |
* was some problem in allocating memory. |
*/ |
int iospace_enable(task_id_t id, void *ioaddr, unsigned long size) |
{ |
87,7 → 80,7 |
/** Interrupt control |
* |
* @param enable 1 - enable interrupts, 0 - disable interrupts |
* @param enable 1 - enable interrupts, 0 - disable interrupts |
*/ |
int preemption_control(int enable) |
{ |
94,36 → 87,5 |
return __SYSCALL1(SYS_PREEMPT_CONTROL, (sysarg_t) enable); |
} |
/** Enable PIO for specified I/O range. |
* |
* @param pio_addr I/O start address. |
* @param size Size of the I/O region. |
* @param use_addr Address where the final address for application's PIO |
* will be stored. |
* |
* @return Zero on success or negative error code. |
*/ |
int pio_enable(void *pio_addr, size_t size, void **use_addr) |
{ |
void *phys; |
void *virt; |
size_t offset; |
unsigned int pages; |
#ifdef IO_SPACE_BOUNDARY |
if (pio_addr < IO_SPACE_BOUNDARY) { |
*use_addr = pio_addr; |
return iospace_enable(task_get_id(), pio_addr, size); |
} |
#endif |
phys = ALIGN_DOWN((uintptr_t) pio_addr, PAGE_SIZE); |
offset = pio_addr - phys; |
pages = ALIGN_UP(offset + size, PAGE_SIZE) >> PAGE_WIDTH; |
virt = as_get_mappable_page(pages); |
*use_addr = virt + offset; |
return physmem_map(phys, virt, pages, AS_AREA_READ | AS_AREA_WRITE); |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/generic/task.c |
---|
1,6 → 1,5 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2008 Jiri Svoboda |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
35,10 → 34,6 |
#include <task.h> |
#include <libc.h> |
#include <stdlib.h> |
#include <errno.h> |
#include <loader/loader.h> |
#include <string.h> |
task_id_t task_get_id(void) |
{ |
49,74 → 44,5 |
return task_id; |
} |
/** Set the task name. |
* |
* @param name The new name, typically the command used to execute the |
* program. |
* @return Zero on success or negative error code. |
*/ |
int task_set_name(const char *name) |
{ |
return __SYSCALL2(SYS_TASK_SET_NAME, (sysarg_t) name, strlen(name)); |
} |
/** Create a new task by running an executable from the filesystem. |
* |
* This is really just a convenience wrapper over the more complicated |
* loader API. |
* |
* @param path pathname of the binary to execute |
* @param argv command-line arguments |
* @return ID of the newly created task or zero on error. |
*/ |
task_id_t task_spawn(const char *path, char *const argv[]) |
{ |
loader_t *ldr; |
task_id_t task_id; |
int rc; |
/* Connect to a program loader. */ |
ldr = loader_connect(); |
if (ldr == NULL) |
return 0; |
/* Get task ID. */ |
rc = loader_get_task_id(ldr, &task_id); |
if (rc != EOK) |
goto error; |
/* Send program pathname. */ |
rc = loader_set_pathname(ldr, path); |
if (rc != EOK) |
goto error; |
/* Send arguments. */ |
rc = loader_set_args(ldr, argv); |
if (rc != EOK) |
goto error; |
/* Load the program. */ |
rc = loader_load_program(ldr); |
if (rc != EOK) |
goto error; |
/* Run it. */ |
rc = loader_run(ldr); |
if (rc != EOK) |
goto error; |
/* Success */ |
free(ldr); |
return task_id; |
/* Error exit */ |
error: |
loader_abort(ldr); |
free(ldr); |
return 0; |
} |
/** @} |
*/ |
/branches/dd/uspace/lib/libc/Makefile |
---|
31,6 → 31,7 |
LIBC_PREFIX = $(shell pwd) |
SOFTINT_PREFIX = ../softint |
CONSOLE_PREFIX = ../../srv/console |
## Setup toolchain |
# |
37,30 → 38,25 |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I$(CONSOLE_PREFIX) |
## Sources |
# |
GENERIC_SOURCES = \ |
generic/libc.c \ |
generic/ddi.c \ |
generic/as.c \ |
generic/cap.c \ |
generic/console.c \ |
generic/mem.c \ |
generic/string.c \ |
generic/fibril.c \ |
generic/pcb.c \ |
generic/smc.c \ |
generic/thread.c \ |
generic/tls.c \ |
generic/task.c \ |
generic/futex.c \ |
generic/io/asprintf.c \ |
generic/io/io.c \ |
generic/io/printf.c \ |
generic/io/fprintf.c \ |
generic/io/stdio.c \ |
generic/io/stream.c \ |
generic/io/sprintf.c \ |
generic/io/snprintf.c \ |
72,49 → 68,44 |
generic/sysinfo.c \ |
generic/ipc.c \ |
generic/async.c \ |
generic/loader.c \ |
generic/getopt.c \ |
generic/libadt/list.o \ |
generic/libadt/hash_table.o \ |
generic/time.c \ |
generic/err.c \ |
generic/stdlib.c \ |
generic/kbd.c \ |
generic/mman.c \ |
generic/udebug.c \ |
generic/vfs/vfs.c \ |
generic/vfs/canonify.c |
ARCH_SOURCES += \ |
arch/$(UARCH)/src/entry.s \ |
arch/$(UARCH)/src/thread_entry.s |
arch/$(ARCH)/src/entry.s \ |
arch/$(ARCH)/src/thread_entry.s |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS) |
.PHONY: all clean depend kerninc |
all: kerninc libc.a arch/$(UARCH)/_link.ld |
all: kerninc libc.a arch/$(ARCH)/_link.ld |
kerninc: |
ln -sfn ../../../../kernel/generic/include include/kernel |
ln -sfn kernel/arch include/arch |
ln -sfn ../arch/$(UARCH)/include include/libarch |
ln -sfn ../arch/$(ARCH)/include include/libarch |
-include Makefile.depend |
clean: |
-rm -f include/kernel include/arch include/libarch libc.a arch/$(UARCH)/_link.ld Makefile.depend |
find generic/ arch/$(UARCH)/ malloc -name '*.o' -follow -exec rm \{\} \; |
-rm -f include/kernel include/arch include/libarch libc.a arch/$(ARCH)/_link.ld Makefile.depend |
find generic/ arch/$(ARCH)/ -name '*.o' -follow -exec rm \{\} \; |
depend: kerninc |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(ARCH_SOURCES) $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libc.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libc.a $(LIBS) $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
arch/$(UARCH)/_link.ld: arch/$(UARCH)/_link.ld.in |
arch/$(ARCH)/_link.ld: arch/$(ARCH)/_link.ld.in |
$(CC) $(DEFS) $(CFLAGS) -DLIBC_PREFIX=$(LIBC_PREFIX) -E -x c $< | grep -v "^\#" > $@ |
%.o: %.S |
/branches/dd/uspace/lib/libc/Makefile.toolchain |
---|
26,23 → 26,16 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -imacros $(LIBC_PREFIX)/../../../config.h -I$(LIBC_PREFIX)/include -pipe -g |
DEFS = -DARCH=$(ARCH) |
CFLAGS = -fno-builtin -Wall -Werror-implicit-function-declaration -Wmissing-prototypes -O3 -nostdlib -nostdinc -I$(LIBC_PREFIX)/include |
LFLAGS = -M -N $(SOFTINT_PREFIX)/libsoftint.a |
AFLAGS = |
#-Werror |
## Cross-toolchain prefix |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
## Setup platform configuration |
# |
-include $(LIBC_PREFIX)/../../../Makefile.config |
-include $(LIBC_PREFIX)/../../../config.defs |
-include $(LIBC_PREFIX)/arch/$(UARCH)/Makefile.inc |
include $(LIBC_PREFIX)/arch/$(ARCH)/Makefile.inc |
## Simple detection of the host system |
# |
66,7 → 59,6 |
AR = $(BINUTILS_PREFIX)ar |
OBJCOPY = $(BINUTILS_PREFIX)objcopy |
OBJDUMP = $(BINUTILS_PREFIX)objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),icc_native) |
76,7 → 68,6 |
AR = ar |
OBJCOPY = objcopy |
OBJDUMP = objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
ifeq ($(COMPILER),gcc_cross) |
86,5 → 77,5 |
AR = $(TOOLCHAIN_DIR)/$(TARGET)-ar |
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
DEPEND_DEFS = $(DEFS) $(CONFIG_DEFS) |
endif |
/branches/dd/uspace/lib/libfs/libfs.c |
---|
160,7 → 160,7 |
len = 0; |
while ((next <= last) && (ops->plb_get_char(next) != '/')) { |
if (len + 1 == NAME_MAX) { |
/* component length overflow */ |
/* comopnent length overflow */ |
ipc_answer_0(rid, ENAMETOOLONG); |
goto out; |
} |
191,20 → 191,17 |
} |
void *nodep; |
if (lflag & L_CREATE) |
nodep = ops->create(dev_handle, lflag); |
nodep = ops->create(lflag); |
else |
nodep = ops->node_get(dev_handle, |
index); |
if (nodep) { |
int rc; |
rc = ops->link(cur, nodep, component); |
if (rc != EOK) { |
if (!ops->link(cur, nodep, component)) { |
if (lflag & L_CREATE) { |
(void)ops->destroy( |
nodep); |
} |
ipc_answer_0(rid, rc); |
ipc_answer_0(rid, ENOSPC); |
} else { |
ipc_answer_5(rid, EOK, |
fs_handle, dev_handle, |
265,17 → 262,14 |
void *nodep; |
if (lflag & L_CREATE) |
nodep = ops->create(dev_handle, lflag); |
nodep = ops->create(lflag); |
else |
nodep = ops->node_get(dev_handle, index); |
if (nodep) { |
int rc; |
rc = ops->link(cur, nodep, component); |
if (rc != EOK) { |
if (!ops->link(cur, nodep, component)) { |
if (lflag & L_CREATE) |
(void)ops->destroy(nodep); |
ipc_answer_0(rid, rc); |
ipc_answer_0(rid, ENOSPC); |
} else { |
ipc_answer_5(rid, EOK, |
fs_handle, dev_handle, |
/branches/dd/uspace/lib/libfs/libfs.h |
---|
45,9 → 45,9 |
void * (* match)(void *, const char *); |
void * (* node_get)(dev_handle_t, fs_index_t); |
void (* node_put)(void *); |
void * (* create)(dev_handle_t, int); |
void * (* create)(int); |
int (* destroy)(void *); |
int (* link)(void *, void *, const char *); |
bool (* link)(void *, void *, const char *); |
int (* unlink)(void *, void *); |
fs_index_t (* index_get)(void *); |
size_t (* size_get)(void *); |
/branches/dd/uspace/lib/libfs/Makefile |
---|
31,7 → 31,6 |
# |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
58,7 → 57,7 |
find . -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
libfs.a: depend $(OBJECTS) |
$(AR) rc libfs.a $(OBJECTS) |
/branches/dd/uspace/lib/softfloat/arch/ppc64/include/functions.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup softfloatppc64 ppc64 |
* @ingroup sfl |
* @brief softfloat architecture dependent definitions |
* @{ |
*/ |
/** @file |
*/ |
#ifndef __SOFTFLOAT_FUNCTIONS_H__ |
#define __SOFTFLOAT_FUNCTIONS_H__ |
#define float32_to_int(X) float32_to_int32(X); |
#define float32_to_long(X) float32_to_int64(X); |
#define float32_to_longlong(X) float32_to_int64(X); |
#define float64_to_int(X) float64_to_int32(X); |
#define float64_to_long(X) float64_to_int64(X); |
#define float64_to_longlong(X) float64_to_int64(X); |
#define float32_to_uint(X) float32_to_uint32(X); |
#define float32_to_ulong(X) float32_to_uint64(X); |
#define float32_to_ulonglong(X) float32_to_uint64(X); |
#define float64_to_uint(X) float64_to_uint32(X); |
#define float64_to_ulong(X) float64_to_uint64(X); |
#define float64_to_ulonglong(X) float64_to_uint64(X); |
#define int_to_float32(X) int32_to_float32(X); |
#define long_to_float32(X) int64_to_float32(X); |
#define longlong_to_float32(X) int64_to_float32(X); |
#define int_to_float64(X) int32_to_float64(X); |
#define long_to_float64(X) int64_to_float64(X); |
#define longlong_to_float64(X) int64_to_float64(X); |
#define uint_to_float32(X) uint32_to_float32(X); |
#define ulong_to_float32(X) uint64_to_float32(X); |
#define ulonglong_to_float32(X) uint64_to_float32(X); |
#define uint_to_float64(X) uint32_to_float64(X); |
#define ulong_to_float64(X) uint64_to_float64(X); |
#define ulonglong_to_float64(X) uint64_to_float64(X); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/lib/softfloat/Makefile |
---|
30,26 → 30,25 |
# |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS +=-Iinclude -Iarch/$(UARCH)/include/ |
CFLAGS +=-Iinclude -Iarch/$(ARCH)/include/ |
## Sources |
# |
GENERIC_SOURCES = \ |
generic/add.c \ |
generic/common.c \ |
generic/comparison.c \ |
generic/conversion.c \ |
generic/div.c \ |
generic/mul.c \ |
generic/other.c \ |
generic/softfloat.c \ |
GENERIC_SOURCES = \ |
generic/add.c \ |
generic/common.c \ |
generic/comparison.c \ |
generic/conversion.c \ |
generic/div.c \ |
generic/mul.c \ |
generic/other.c \ |
generic/softfloat.c \ |
generic/sub.c |
ARCH_SOURCES = |
67,7 → 66,7 |
find generic/ -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEND_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libsoftfloat.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libsoftfloat.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
/branches/dd/uspace/lib/softint/Makefile |
---|
30,7 → 30,6 |
# |
LIBC_PREFIX = ../libc |
## Setup toolchain |
# |
59,7 → 58,7 |
find generic/ -name '*.o' -follow -exec rm \{\} \; |
depend: |
-makedepend -f - -- $(DEPEMD_DEFS) $(CFLAGS) -- $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(GENERIC_SOURCES) > Makefile.depend 2> /dev/null |
libsoftint.a: depend $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
$(AR) rc libsoftint.a $(ARCH_OBJECTS) $(GENERIC_OBJECTS) |
/branches/dd/uspace/srv/fhc/Makefile |
---|
File deleted |
/branches/dd/uspace/srv/fhc/fhc.c |
---|
File deleted |
/branches/dd/uspace/srv/loader/elf_load.c |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia64/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia64/ia64.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia64/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/arm32/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/arm32/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/arm32/arm32.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/mips32eb |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/dd/uspace/srv/loader/arch/ppc32/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ppc32/ppc32.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ppc32/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/amd64/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/amd64/amd64.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/amd64/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/mips32/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/mips32/mips32.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/mips32/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia32/ia32.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia32/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/ia32/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/sparc64/_link.ld.in |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/sparc64/sparc64.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/arch/sparc64/Makefile.inc |
---|
File deleted |
/branches/dd/uspace/srv/loader/Makefile |
---|
File deleted |
/branches/dd/uspace/srv/loader/interp.s |
---|
File deleted |
/branches/dd/uspace/srv/loader/include/arch.h |
---|
File deleted |
/branches/dd/uspace/srv/loader/include/elf_load.h |
---|
File deleted |
/branches/dd/uspace/srv/loader/include/elf.h |
---|
File deleted |
/branches/dd/uspace/srv/loader/main.c |
---|
File deleted |
/branches/dd/uspace/srv/obio/obio.c |
---|
File deleted |
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/uspace/srv/obio/Makefile |
---|
File deleted |
/branches/dd/uspace/srv/obio |
---|
Property changes: |
Deleted: svn:mergeinfo |
/branches/dd/uspace/srv/fs/tmpfs/tmpfs_dump.c |
---|
File deleted |
/branches/dd/uspace/srv/fs/tmpfs/tmpfs.h |
---|
40,16 → 40,8 |
#include <bool.h> |
#include <libadt/hash_table.h> |
#ifndef dprintf |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
typedef enum { |
TMPFS_NONE, |
TMPFS_FILE, |
TMPFS_DIRECTORY |
} tmpfs_dentry_type_t; |
typedef struct tmpfs_dentry { |
fs_index_t index; /**< TMPFS node index. */ |
link_t dh_link; /**< Dentries hash table link. */ |
56,7 → 48,11 |
struct tmpfs_dentry *sibling; |
struct tmpfs_dentry *child; |
hash_table_t names; /**< All names linking to this TMPFS node. */ |
tmpfs_dentry_type_t type; |
enum { |
TMPFS_NONE, |
TMPFS_FILE, |
TMPFS_DIRECTORY |
} type; |
unsigned lnkcnt; /**< Link count. */ |
size_t size; /**< File size if type is TMPFS_FILE. */ |
void *data; /**< File content's if type is TMPFS_FILE. */ |
64,9 → 60,6 |
extern fs_reg_t tmpfs_reg; |
extern libfs_ops_t tmpfs_libfs_ops; |
extern void tmpfs_mounted(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_mount(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_lookup(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_read(ipc_callid_t, ipc_call_t *); |
74,8 → 67,6 |
extern void tmpfs_truncate(ipc_callid_t, ipc_call_t *); |
extern void tmpfs_destroy(ipc_callid_t, ipc_call_t *); |
extern bool tmpfs_restore(dev_handle_t); |
#endif |
/** |
/branches/dd/uspace/srv/fs/tmpfs/tmpfs.c |
---|
50,11 → 50,18 |
#include <libfs.h> |
#include "../../vfs/vfs.h" |
#define NAME "tmpfs" |
vfs_info_t tmpfs_vfs_info = { |
.name = "tmpfs", |
.ops = { |
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_DESTROY)] = VFS_OP_DEFINED, |
} |
}; |
fs_reg_t tmpfs_reg; |
96,9 → 103,6 |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case VFS_MOUNTED: |
tmpfs_mounted(callid, &call); |
break; |
case VFS_MOUNT: |
tmpfs_mount(callid, &call); |
break; |
126,22 → 130,27 |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS TMPFS file system server\n"); |
int vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); |
if (vfs_phone < EOK) { |
printf(NAME ": Unable to connect to VFS\n"); |
return -1; |
int vfs_phone; |
printf("TMPFS: HelenOS TMPFS file system server.\n"); |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
while (vfs_phone < EOK) { |
usleep(10000); |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
} |
int rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info, |
int rc; |
rc = fs_register(vfs_phone, &tmpfs_reg, &tmpfs_vfs_info, |
tmpfs_connection); |
if (rc != EOK) { |
printf(NAME ": Failed to register file system (%d)\n", rc); |
printf("Failed to register the TMPFS file system (%d)\n", rc); |
return rc; |
} |
printf(NAME ": Accepting connections\n"); |
dprintf("TMPFS filesystem registered, fs_handle=%d.\n", |
tmpfs_reg.fs_handle); |
async_manager(); |
/* not reached */ |
return 0; |
/branches/dd/uspace/srv/fs/tmpfs/tmpfs_ops.c |
---|
64,8 → 64,6 |
*/ |
static tmpfs_dentry_t *root; |
#define TMPFS_DEV 0 /**< Dummy device handle for TMPFS */ |
/* |
* Implementation of the libfs interface. |
*/ |
74,8 → 72,8 |
static void *tmpfs_match(void *, const char *); |
static void *tmpfs_node_get(dev_handle_t, fs_index_t); |
static void tmpfs_node_put(void *); |
static void *tmpfs_create_node(dev_handle_t, int); |
static int tmpfs_link_node(void *, void *, const char *); |
static void *tmpfs_create_node(int); |
static bool tmpfs_link_node(void *, void *, const char *); |
static int tmpfs_unlink_node(void *, void *); |
static int tmpfs_destroy_node(void *); |
230,12 → 228,12 |
{ |
if (!hash_table_create(&dentries, DENTRIES_BUCKETS, 1, &dentries_ops)) |
return false; |
root = (tmpfs_dentry_t *) tmpfs_create_node(TMPFS_DEV, L_DIRECTORY); |
root = (tmpfs_dentry_t *) tmpfs_create_node(L_DIRECTORY); |
if (!root) { |
hash_table_destroy(&dentries); |
return false; |
} |
root->lnkcnt = 0; /* FS root is not linked */ |
root->lnkcnt = 1; |
return true; |
} |
284,7 → 282,7 |
/* nothing to do */ |
} |
void *tmpfs_create_node(dev_handle_t dev_handle, int lflag) |
void *tmpfs_create_node(int lflag) |
{ |
assert((lflag & L_FILE) ^ (lflag & L_DIRECTORY)); |
308,7 → 306,7 |
return (void *) node; |
} |
int tmpfs_link_node(void *prnt, void *chld, const char *nm) |
bool tmpfs_link_node(void *prnt, void *chld, const char *nm) |
{ |
tmpfs_dentry_t *parentp = (tmpfs_dentry_t *) prnt; |
tmpfs_dentry_t *childp = (tmpfs_dentry_t *) chld; |
317,13 → 315,13 |
tmpfs_name_t *namep = malloc(sizeof(tmpfs_name_t)); |
if (!namep) |
return ENOMEM; |
return false; |
tmpfs_name_initialize(namep); |
size_t len = strlen(nm); |
namep->name = malloc(len + 1); |
if (!namep->name) { |
free(namep); |
return ENOMEM; |
return false; |
} |
strcpy(namep->name, nm); |
namep->parent = parentp; |
343,7 → 341,7 |
parentp->child = childp; |
} |
return EOK; |
return true; |
} |
int tmpfs_unlink_node(void *prnt, void *chld) |
395,39 → 393,28 |
return EOK; |
} |
void tmpfs_mounted(ipc_callid_t rid, ipc_call_t *request) |
void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
dev_handle_t mr_dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t mr_index = (fs_index_t)IPC_GET_ARG2(*request); |
fs_handle_t mp_fs_handle = (fs_handle_t)IPC_GET_ARG3(*request); |
dev_handle_t mp_dev_handle = (dev_handle_t)IPC_GET_ARG4(*request); |
fs_index_t mp_index = (fs_index_t)IPC_GET_ARG5(*request); |
if ((mr_index == root->index) && |
(mp_fs_handle == tmpfs_reg.fs_handle) && |
(mp_index == mr_index)) |
ipc_answer_0(rid, EOK); |
else |
ipc_answer_0(rid, ENOTSUP); |
} |
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* Initialize TMPFS. */ |
if (!root && !tmpfs_init()) { |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
if (dev_handle >= 0) { |
if (tmpfs_restore(dev_handle)) |
ipc_answer_3(rid, EOK, root->index, root->size, |
root->lnkcnt); |
else |
ipc_answer_0(rid, ELIMIT); |
} else { |
ipc_answer_3(rid, EOK, root->index, root->size, root->lnkcnt); |
} |
} |
void tmpfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t mp_dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
fs_index_t mp_index = (fs_index_t) IPC_GET_ARG2(*request); |
fs_handle_t mr_fs_handle = (fs_handle_t) IPC_GET_ARG3(*request); |
dev_handle_t mr_dev_handle = (dev_handle_t) IPC_GET_ARG4(*request); |
ipc_answer_0(rid, ENOTSUP); |
} |
void tmpfs_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
libfs_lookup(&tmpfs_libfs_ops, tmpfs_reg.fs_handle, rid, request); |
} |
/branches/dd/uspace/srv/fs/tmpfs/Makefile |
---|
31,17 → 31,12 |
LIBC_PREFIX = ../../../lib/libc |
LIBFS_PREFIX = ../../../lib/libfs |
LIBBLOCK_PREFIX = ../../../lib/libblock |
SOFTINT_PREFIX = ../../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) |
CFLAGS += -I $(LIBFS_PREFIX) |
LIBS = \ |
$(LIBFS_PREFIX)/libfs.a \ |
$(LIBBLOCK_PREFIX)/libblock.a \ |
$(LIBC_PREFIX)/libc.a |
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a |
## Sources |
# |
49,31 → 44,28 |
OUTPUT = tmpfs |
SOURCES = \ |
tmpfs.c \ |
tmpfs_ops.c \ |
tmpfs_dump.c |
tmpfs_ops.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/fs/fat/fat_fat.c |
---|
File deleted |
/branches/dd/uspace/srv/fs/fat/fat_dentry.c |
---|
File deleted |
/branches/dd/uspace/srv/fs/fat/fat_dentry.h |
---|
File deleted |
/branches/dd/uspace/srv/fs/fat/fat_fat.h |
---|
File deleted |
/branches/dd/uspace/srv/fs/fat/fat_ops.c |
---|
36,14 → 36,9 |
*/ |
#include "fat.h" |
#include "fat_dentry.h" |
#include "fat_fat.h" |
#include "../../vfs/vfs.h" |
#include <libfs.h> |
#include <libblock.h> |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <ipc/devmap.h> |
#include <async.h> |
#include <errno.h> |
#include <string.h> |
52,9 → 47,9 |
#include <libadt/list.h> |
#include <assert.h> |
#include <futex.h> |
#include <sys/mman.h> |
#include <align.h> |
#define BS_BLOCK 0 |
/** Futex protecting the list of cached free FAT nodes. */ |
static futex_t ffn_futex = FUTEX_INITIALIZER; |
61,6 → 56,130 |
/** List of cached free FAT nodes. */ |
static LIST_INITIALIZE(ffn_head); |
#define FAT_NAME_LEN 8 |
#define FAT_EXT_LEN 3 |
#define FAT_PAD ' ' |
#define FAT_DENTRY_UNUSED 0x00 |
#define FAT_DENTRY_E5_ESC 0x05 |
#define FAT_DENTRY_DOT 0x2e |
#define FAT_DENTRY_ERASED 0xe5 |
static void dentry_name_canonify(fat_dentry_t *d, char *buf) |
{ |
int i; |
for (i = 0; i < FAT_NAME_LEN; i++) { |
if (d->name[i] == FAT_PAD) { |
buf++; |
break; |
} |
if (d->name[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->name[i]; |
} |
if (d->ext[0] != FAT_PAD) |
*buf++ = '.'; |
for (i = 0; i < FAT_EXT_LEN; i++) { |
if (d->ext[i] == FAT_PAD) { |
*buf = '\0'; |
return; |
} |
if (d->ext[i] == FAT_DENTRY_E5_ESC) |
*buf++ = 0xe5; |
else |
*buf++ = d->ext[i]; |
} |
} |
/* TODO move somewhere else */ |
typedef struct { |
void *data; |
} block_t; |
static block_t *block_get(dev_handle_t dev_handle, off_t offset) |
{ |
return NULL; /* TODO */ |
} |
static void block_put(block_t *block) |
{ |
/* TODO */ |
} |
#define FAT_BS(b) ((fat_bs_t *)((b)->data)) |
#define FAT_CLST_RES0 0x0000 |
#define FAT_CLST_RES1 0x0001 /* internally used to mark root directory */ |
#define FAT_CLST_FIRST 0x0002 |
#define FAT_CLST_BAD 0xfff7 |
#define FAT_CLST_LAST1 0xfff8 |
#define FAT_CLST_LAST8 0xffff |
#define fat_block_get(np, off) \ |
_fat_block_get((np)->idx->dev_handle, (np)->firstc, (off)) |
static block_t * |
_fat_block_get(dev_handle_t dev_handle, fat_cluster_t firstc, off_t offset) |
{ |
block_t *bb; |
block_t *b; |
unsigned bps; |
unsigned spc; |
unsigned rscnt; /* block address of the first FAT */ |
unsigned fatcnt; |
unsigned rde; |
unsigned rds; /* root directory size */ |
unsigned sf; |
unsigned ssa; /* size of the system area */ |
unsigned clusters; |
fat_cluster_t clst = firstc; |
unsigned i; |
bb = block_get(dev_handle, BS_BLOCK); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
spc = FAT_BS(bb)->spc; |
rscnt = uint16_t_le2host(FAT_BS(bb)->rscnt); |
fatcnt = FAT_BS(bb)->fatcnt; |
rde = uint16_t_le2host(FAT_BS(bb)->root_ent_max); |
sf = uint16_t_le2host(FAT_BS(bb)->sec_per_fat); |
block_put(bb); |
rds = (sizeof(fat_dentry_t) * rde) / bps; |
rds += ((sizeof(fat_dentry_t) * rde) % bps != 0); |
ssa = rscnt + fatcnt * sf + rds; |
if (firstc == FAT_CLST_RES1) { |
/* root directory special case */ |
assert(offset < rds); |
b = block_get(dev_handle, rscnt + fatcnt * sf + offset); |
return b; |
} |
clusters = offset / spc; |
for (i = 0; i < clusters; i++) { |
unsigned fsec; /* sector offset relative to FAT1 */ |
unsigned fidx; /* FAT1 entry index */ |
assert(clst >= FAT_CLST_FIRST && clst < FAT_CLST_BAD); |
fsec = (clst * sizeof(fat_cluster_t)) / bps; |
fidx = clst % (bps / sizeof(fat_cluster_t)); |
/* read FAT1 */ |
b = block_get(dev_handle, rscnt + fsec); |
clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); |
assert(clst != FAT_CLST_BAD); |
assert(clst < FAT_CLST_LAST1); |
block_put(b); |
} |
b = block_get(dev_handle, ssa + (clst - FAT_CLST_FIRST) * spc + |
offset % spc); |
return b; |
} |
static void fat_node_initialize(fat_node_t *node) |
{ |
futex_initialize(&node->lock, 1); |
73,43 → 192,84 |
node->dirty = false; |
} |
static void fat_node_sync(fat_node_t *node) |
static uint16_t fat_bps_get(dev_handle_t dev_handle) |
{ |
block_t *b; |
fat_bs_t *bs; |
fat_dentry_t *d; |
block_t *bb; |
uint16_t bps; |
unsigned dps; |
assert(node->dirty); |
bb = block_get(dev_handle, BS_BLOCK); |
assert(bb != NULL); |
bps = uint16_t_le2host(FAT_BS(bb)->bps); |
block_put(bb); |
bs = block_bb_get(node->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc, |
(node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); |
return bps; |
} |
d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps); |
typedef enum { |
FAT_DENTRY_SKIP, |
FAT_DENTRY_LAST, |
FAT_DENTRY_VALID |
} fat_dentry_clsf_t; |
d->firstc = host2uint16_t_le(node->firstc); |
if (node->type == FAT_FILE) { |
d->size = host2uint32_t_le(node->size); |
} else if (node->type == FAT_DIRECTORY) { |
d->attr = FAT_ATTR_SUBDIR; |
static fat_dentry_clsf_t fat_classify_dentry(fat_dentry_t *d) |
{ |
if (d->attr & FAT_ATTR_VOLLABEL) { |
/* volume label entry */ |
return FAT_DENTRY_SKIP; |
} |
/* TODO: update other fields? (e.g time fields) */ |
b->dirty = true; /* need to sync block */ |
block_put(b); |
if (d->name[0] == FAT_DENTRY_ERASED) { |
/* not-currently-used entry */ |
return FAT_DENTRY_SKIP; |
} |
if (d->name[0] == FAT_DENTRY_UNUSED) { |
/* never used entry */ |
return FAT_DENTRY_LAST; |
} |
if (d->name[0] == FAT_DENTRY_DOT) { |
/* |
* Most likely '.' or '..'. |
* It cannot occur in a regular file name. |
*/ |
return FAT_DENTRY_SKIP; |
} |
return FAT_DENTRY_VALID; |
} |
static fat_node_t *fat_node_get_new(void) |
static void fat_node_sync(fat_node_t *node) |
{ |
/* TODO */ |
} |
/** Internal version of fat_node_get(). |
* |
* @param idxp Locked index structure. |
*/ |
static void *fat_node_get_core(fat_idx_t *idxp) |
{ |
block_t *b; |
fat_dentry_t *d; |
fat_node_t *nodep; |
unsigned bps; |
unsigned dps; |
if (idxp->nodep) { |
/* |
* We are lucky. |
* The node is already instantiated in memory. |
*/ |
futex_down(&idxp->nodep->lock); |
if (!idxp->nodep->refcnt++) |
list_remove(&nodep->ffn_link); |
futex_up(&idxp->nodep->lock); |
return idxp->nodep; |
} |
/* |
* We must instantiate the node from the file system. |
*/ |
assert(idxp->pfc); |
futex_down(&ffn_futex); |
if (!list_empty(&ffn_head)) { |
/* Try to use a cached free node structure. */ |
138,54 → 298,13 |
return NULL; |
} |
fat_node_initialize(nodep); |
return nodep; |
} |
/** Internal version of fat_node_get(). |
* |
* @param idxp Locked index structure. |
*/ |
static void *fat_node_get_core(fat_idx_t *idxp) |
{ |
block_t *b; |
fat_bs_t *bs; |
fat_dentry_t *d; |
fat_node_t *nodep = NULL; |
unsigned bps; |
unsigned spc; |
unsigned dps; |
if (idxp->nodep) { |
/* |
* We are lucky. |
* The node is already instantiated in memory. |
*/ |
futex_down(&idxp->nodep->lock); |
if (!idxp->nodep->refcnt++) |
list_remove(&idxp->nodep->ffn_link); |
futex_up(&idxp->nodep->lock); |
return idxp->nodep; |
} |
/* |
* We must instantiate the node from the file system. |
*/ |
assert(idxp->pfc); |
nodep = fat_node_get_new(); |
if (!nodep) |
return NULL; |
bs = block_bb_get(idxp->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
bps = fat_bps_get(idxp->dev_handle); |
dps = bps / sizeof(fat_dentry_t); |
/* Read the block that contains the dentry of interest. */ |
b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc, |
(idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); |
b = _fat_block_get(idxp->dev_handle, idxp->pfc, |
(idxp->pdi * sizeof(fat_dentry_t)) / bps); |
assert(b); |
d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps); |
196,18 → 315,11 |
* and initialized elsewhere. |
*/ |
nodep->type = FAT_DIRECTORY; |
/* |
* Unfortunately, the 'size' field of the FAT dentry is not |
* defined for the directory entry type. We must determine the |
* size of the directory by walking the FAT. |
*/ |
nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle, |
uint16_t_le2host(d->firstc)); |
} else { |
nodep->type = FAT_FILE; |
nodep->size = uint32_t_le2host(d->size); |
} |
nodep->firstc = uint16_t_le2host(d->firstc); |
nodep->size = uint32_t_le2host(d->size); |
nodep->lnkcnt = 1; |
nodep->refcnt = 1; |
220,31 → 332,8 |
return nodep; |
} |
/* |
* Forward declarations of FAT libfs operations. |
*/ |
static void *fat_node_get(dev_handle_t, fs_index_t); |
static void fat_node_put(void *); |
static void *fat_create_node(dev_handle_t, int); |
static int fat_destroy_node(void *); |
static int fat_link(void *, void *, const char *); |
static int fat_unlink(void *, void *); |
static void *fat_match(void *, const char *); |
static fs_index_t fat_index_get(void *); |
static size_t fat_size_get(void *); |
static unsigned fat_lnkcnt_get(void *); |
static bool fat_has_children(void *); |
static void *fat_root_get(dev_handle_t); |
static char fat_plb_get_char(unsigned); |
static bool fat_is_directory(void *); |
static bool fat_is_file(void *node); |
/* |
* FAT libfs operations. |
*/ |
/** Instantiate a FAT in-core node. */ |
void *fat_node_get(dev_handle_t dev_handle, fs_index_t index) |
static void *fat_node_get(dev_handle_t dev_handle, fs_index_t index) |
{ |
void *node; |
fat_idx_t *idxp; |
258,318 → 347,41 |
return node; |
} |
void fat_node_put(void *node) |
static void fat_node_put(void *node) |
{ |
fat_node_t *nodep = (fat_node_t *)node; |
bool destroy = false; |
futex_down(&nodep->lock); |
if (!--nodep->refcnt) { |
if (nodep->idx) { |
futex_down(&ffn_futex); |
list_append(&nodep->ffn_link, &ffn_head); |
futex_up(&ffn_futex); |
} else { |
/* |
* The node does not have any index structure associated |
* with itself. This can only mean that we are releasing |
* the node after a failed attempt to allocate the index |
* structure for it. |
*/ |
destroy = true; |
} |
futex_down(&ffn_futex); |
list_append(&nodep->ffn_link, &ffn_head); |
futex_up(&ffn_futex); |
} |
futex_up(&nodep->lock); |
if (destroy) |
free(node); |
} |
void *fat_create_node(dev_handle_t dev_handle, int flags) |
static void *fat_create(int flags) |
{ |
fat_idx_t *idxp; |
fat_node_t *nodep; |
fat_bs_t *bs; |
fat_cluster_t mcl, lcl; |
uint16_t bps; |
int rc; |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
if (flags & L_DIRECTORY) { |
/* allocate a cluster */ |
rc = fat_alloc_clusters(bs, dev_handle, 1, &mcl, &lcl); |
if (rc != EOK) |
return NULL; |
} |
nodep = fat_node_get_new(); |
if (!nodep) { |
fat_free_clusters(bs, dev_handle, mcl); |
return NULL; |
} |
idxp = fat_idx_get_new(dev_handle); |
if (!idxp) { |
fat_free_clusters(bs, dev_handle, mcl); |
fat_node_put(nodep); |
return NULL; |
} |
/* idxp->lock held */ |
if (flags & L_DIRECTORY) { |
int i; |
block_t *b; |
/* |
* Populate the new cluster with unused dentries. |
*/ |
for (i = 0; i < bs->spc; i++) { |
b = _fat_block_get(bs, dev_handle, mcl, i, |
BLOCK_FLAGS_NOREAD); |
/* mark all dentries as never-used */ |
memset(b->data, 0, bps); |
b->dirty = false; |
block_put(b); |
} |
nodep->type = FAT_DIRECTORY; |
nodep->firstc = mcl; |
nodep->size = bps * bs->spc; |
} else { |
nodep->type = FAT_FILE; |
nodep->firstc = FAT_CLST_RES0; |
nodep->size = 0; |
} |
nodep->lnkcnt = 0; /* not linked anywhere */ |
nodep->refcnt = 1; |
nodep->dirty = true; |
nodep->idx = idxp; |
idxp->nodep = nodep; |
futex_up(&idxp->lock); |
return nodep; |
return NULL; /* not supported at the moment */ |
} |
int fat_destroy_node(void *node) |
static int fat_destroy(void *node) |
{ |
fat_node_t *nodep = (fat_node_t *)node; |
fat_bs_t *bs; |
/* |
* The node is not reachable from the file system. This means that the |
* link count should be zero and that the index structure cannot be |
* found in the position hash. Obviously, we don't need to lock the node |
* nor its index structure. |
*/ |
assert(nodep->lnkcnt == 0); |
/* |
* The node may not have any children. |
*/ |
assert(fat_has_children(node) == false); |
bs = block_bb_get(nodep->idx->dev_handle); |
if (nodep->firstc != FAT_CLST_RES0) { |
assert(nodep->size); |
/* Free all clusters allocated to the node. */ |
fat_free_clusters(bs, nodep->idx->dev_handle, nodep->firstc); |
} |
fat_idx_destroy(nodep->idx); |
free(nodep); |
return EOK; |
return ENOTSUP; /* not supported at the moment */ |
} |
int fat_link(void *prnt, void *chld, const char *name) |
static bool fat_link(void *prnt, void *chld, const char *name) |
{ |
fat_node_t *parentp = (fat_node_t *)prnt; |
fat_node_t *childp = (fat_node_t *)chld; |
fat_dentry_t *d; |
fat_bs_t *bs; |
block_t *b; |
int i, j; |
uint16_t bps; |
unsigned dps; |
unsigned blocks; |
fat_cluster_t mcl, lcl; |
int rc; |
futex_down(&childp->lock); |
if (childp->lnkcnt == 1) { |
/* |
* On FAT, we don't support multiple hard links. |
*/ |
futex_up(&childp->lock); |
return EMLINK; |
} |
assert(childp->lnkcnt == 0); |
futex_up(&childp->lock); |
if (!fat_dentry_name_verify(name)) { |
/* |
* Attempt to create unsupported name. |
*/ |
return ENOTSUP; |
} |
/* |
* Get us an unused parent node's dentry or grow the parent and allocate |
* a new one. |
*/ |
futex_down(&parentp->idx->lock); |
bs = block_bb_get(parentp->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
dps = bps / sizeof(fat_dentry_t); |
blocks = parentp->size / bps; |
for (i = 0; i < blocks; i++) { |
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); |
for (j = 0; j < dps; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
case FAT_DENTRY_VALID: |
/* skipping used and meta entries */ |
continue; |
case FAT_DENTRY_FREE: |
case FAT_DENTRY_LAST: |
/* found an empty slot */ |
goto hit; |
} |
} |
block_put(b); |
} |
j = 0; |
/* |
* We need to grow the parent in order to create a new unused dentry. |
*/ |
if (parentp->idx->pfc == FAT_CLST_ROOT) { |
/* Can't grow the root directory. */ |
futex_up(&parentp->idx->lock); |
return ENOSPC; |
} |
rc = fat_alloc_clusters(bs, parentp->idx->dev_handle, 1, &mcl, &lcl); |
if (rc != EOK) { |
futex_up(&parentp->idx->lock); |
return rc; |
} |
fat_append_clusters(bs, parentp, mcl); |
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NOREAD); |
d = (fat_dentry_t *)b->data; |
/* |
* Clear all dentries in the block except for the first one (the first |
* dentry will be cleared in the next step). |
*/ |
memset(d + 1, 0, bps - sizeof(fat_dentry_t)); |
hit: |
/* |
* At this point we only establish the link between the parent and the |
* child. The dentry, except of the name and the extension, will remain |
* uninitialized until the corresponding node is synced. Thus the valid |
* dentry data is kept in the child node structure. |
*/ |
memset(d, 0, sizeof(fat_dentry_t)); |
fat_dentry_name_set(d, name); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
futex_up(&parentp->idx->lock); |
futex_down(&childp->idx->lock); |
/* |
* If possible, create the Sub-directory Identifier Entry and the |
* Sub-directory Parent Pointer Entry (i.e. "." and ".."). These entries |
* are not mandatory according to Standard ECMA-107 and HelenOS VFS does |
* not use them anyway, so this is rather a sign of our good will. |
*/ |
b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE); |
d = (fat_dentry_t *)b->data; |
if (fat_classify_dentry(d) == FAT_DENTRY_LAST || |
strcmp(d->name, FAT_NAME_DOT) == 0) { |
memset(d, 0, sizeof(fat_dentry_t)); |
strcpy(d->name, FAT_NAME_DOT); |
strcpy(d->ext, FAT_EXT_PAD); |
d->attr = FAT_ATTR_SUBDIR; |
d->firstc = host2uint16_t_le(childp->firstc); |
/* TODO: initialize also the date/time members. */ |
} |
d++; |
if (fat_classify_dentry(d) == FAT_DENTRY_LAST || |
strcmp(d->name, FAT_NAME_DOT_DOT) == 0) { |
memset(d, 0, sizeof(fat_dentry_t)); |
strcpy(d->name, FAT_NAME_DOT_DOT); |
strcpy(d->ext, FAT_EXT_PAD); |
d->attr = FAT_ATTR_SUBDIR; |
d->firstc = (parentp->firstc == FAT_CLST_ROOT) ? |
host2uint16_t_le(FAT_CLST_RES0) : |
host2uint16_t_le(parentp->firstc); |
/* TODO: initialize also the date/time members. */ |
} |
b->dirty = true; /* need to sync block */ |
block_put(b); |
childp->idx->pfc = parentp->firstc; |
childp->idx->pdi = i * dps + j; |
futex_up(&childp->idx->lock); |
futex_down(&childp->lock); |
childp->lnkcnt = 1; |
childp->dirty = true; /* need to sync node */ |
futex_up(&childp->lock); |
/* |
* Hash in the index structure into the position hash. |
*/ |
fat_idx_hashin(childp->idx); |
return EOK; |
return false; /* not supported at the moment */ |
} |
int fat_unlink(void *prnt, void *chld) |
static int fat_unlink(void *prnt, void *chld) |
{ |
fat_node_t *parentp = (fat_node_t *)prnt; |
fat_node_t *childp = (fat_node_t *)chld; |
fat_bs_t *bs; |
fat_dentry_t *d; |
uint16_t bps; |
block_t *b; |
futex_down(&parentp->lock); |
futex_down(&childp->lock); |
assert(childp->lnkcnt == 1); |
futex_down(&childp->idx->lock); |
bs = block_bb_get(childp->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
b = _fat_block_get(bs, childp->idx->dev_handle, childp->idx->pfc, |
(childp->idx->pdi * sizeof(fat_dentry_t)) / bps, |
BLOCK_FLAGS_NONE); |
d = (fat_dentry_t *)b->data + |
(childp->idx->pdi % (bps / sizeof(fat_dentry_t))); |
/* mark the dentry as not-currently-used */ |
d->name[0] = FAT_DENTRY_ERASED; |
b->dirty = true; /* need to sync block */ |
block_put(b); |
/* remove the index structure from the position hash */ |
fat_idx_hashout(childp->idx); |
/* clear position information */ |
childp->idx->pfc = FAT_CLST_RES0; |
childp->idx->pdi = 0; |
futex_up(&childp->idx->lock); |
childp->lnkcnt = 0; |
childp->dirty = true; |
futex_up(&childp->lock); |
futex_up(&parentp->lock); |
return EOK; |
return ENOTSUP; /* not supported at the moment */ |
} |
void *fat_match(void *prnt, const char *component) |
static void *fat_match(void *prnt, const char *component) |
{ |
fat_bs_t *bs; |
fat_node_t *parentp = (fat_node_t *)prnt; |
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; |
unsigned i, j; |
580,17 → 392,20 |
block_t *b; |
futex_down(&parentp->idx->lock); |
bs = block_bb_get(parentp->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
bps = fat_bps_get(parentp->idx->dev_handle); |
dps = bps / sizeof(fat_dentry_t); |
blocks = parentp->size / bps; |
blocks = parentp->size / bps + (parentp->size % bps != 0); |
for (i = 0; i < blocks; i++) { |
b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); |
for (j = 0; j < dps; j++) { |
unsigned dentries; |
b = fat_block_get(parentp, i); |
dentries = (i == blocks - 1) ? |
parentp->size % sizeof(fat_dentry_t) : |
dps; |
for (j = 0; j < dentries; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
case FAT_DENTRY_FREE: |
continue; |
case FAT_DENTRY_LAST: |
block_put(b); |
598,10 → 413,10 |
return NULL; |
default: |
case FAT_DENTRY_VALID: |
fat_dentry_name_get(d, name); |
dentry_name_canonify(d, name); |
break; |
} |
if (fat_dentry_namecmp(name, component) == 0) { |
if (strcmp(name, component) == 0) { |
/* hit */ |
void *node; |
/* |
630,12 → 445,11 |
} |
block_put(b); |
} |
futex_up(&parentp->idx->lock); |
return NULL; |
} |
fs_index_t fat_index_get(void *node) |
static fs_index_t fat_index_get(void *node) |
{ |
fat_node_t *fnodep = (fat_node_t *)node; |
if (!fnodep) |
643,19 → 457,18 |
return fnodep->idx->index; |
} |
size_t fat_size_get(void *node) |
static size_t fat_size_get(void *node) |
{ |
return ((fat_node_t *)node)->size; |
} |
unsigned fat_lnkcnt_get(void *node) |
static unsigned fat_lnkcnt_get(void *node) |
{ |
return ((fat_node_t *)node)->lnkcnt; |
} |
bool fat_has_children(void *node) |
static bool fat_has_children(void *node) |
{ |
fat_bs_t *bs; |
fat_node_t *nodep = (fat_node_t *)node; |
unsigned bps; |
unsigned dps; |
665,23 → 478,25 |
if (nodep->type != FAT_DIRECTORY) |
return false; |
futex_down(&nodep->idx->lock); |
bs = block_bb_get(nodep->idx->dev_handle); |
bps = uint16_t_le2host(bs->bps); |
bps = fat_bps_get(nodep->idx->dev_handle); |
dps = bps / sizeof(fat_dentry_t); |
blocks = nodep->size / bps; |
blocks = nodep->size / bps + (nodep->size % bps != 0); |
for (i = 0; i < blocks; i++) { |
unsigned dentries; |
fat_dentry_t *d; |
b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE); |
for (j = 0; j < dps; j++) { |
b = fat_block_get(nodep, i); |
dentries = (i == blocks - 1) ? |
nodep->size % sizeof(fat_dentry_t) : |
dps; |
for (j = 0; j < dentries; j++) { |
d = ((fat_dentry_t *)b->data) + j; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
case FAT_DENTRY_FREE: |
continue; |
case FAT_DENTRY_LAST: |
block_put(b); |
704,22 → 519,22 |
return false; |
} |
void *fat_root_get(dev_handle_t dev_handle) |
static void *fat_root_get(dev_handle_t dev_handle) |
{ |
return fat_node_get(dev_handle, 0); |
return NULL; /* TODO */ |
} |
char fat_plb_get_char(unsigned pos) |
static char fat_plb_get_char(unsigned pos) |
{ |
return fat_reg.plb_ro[pos % PLB_SIZE]; |
} |
bool fat_is_directory(void *node) |
static bool fat_is_directory(void *node) |
{ |
return ((fat_node_t *)node)->type == FAT_DIRECTORY; |
} |
bool fat_is_file(void *node) |
static bool fat_is_file(void *node) |
{ |
return ((fat_node_t *)node)->type == FAT_FILE; |
} |
729,8 → 544,8 |
.match = fat_match, |
.node_get = fat_node_get, |
.node_put = fat_node_put, |
.create = fat_create_node, |
.destroy = fat_destroy_node, |
.create = fat_create, |
.destroy = fat_destroy, |
.link = fat_link, |
.unlink = fat_unlink, |
.index_get = fat_index_get, |
743,388 → 558,11 |
.is_file = fat_is_file |
}; |
/* |
* VFS operations. |
*/ |
void fat_mounted(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
fat_bs_t *bs; |
uint16_t bps; |
uint16_t rde; |
int rc; |
/* initialize libblock */ |
rc = block_init(dev_handle, BS_SIZE); |
if (rc != EOK) { |
ipc_answer_0(rid, rc); |
return; |
} |
/* prepare the boot block */ |
rc = block_bb_read(dev_handle, BS_BLOCK * BS_SIZE, BS_SIZE); |
if (rc != EOK) { |
block_fini(dev_handle); |
ipc_answer_0(rid, rc); |
return; |
} |
/* get the buffer with the boot sector */ |
bs = block_bb_get(dev_handle); |
/* Read the number of root directory entries. */ |
bps = uint16_t_le2host(bs->bps); |
rde = uint16_t_le2host(bs->root_ent_max); |
if (bps != BS_SIZE) { |
block_fini(dev_handle); |
ipc_answer_0(rid, ENOTSUP); |
return; |
} |
/* Initialize the block cache */ |
rc = block_cache_init(dev_handle, bps, 0 /* XXX */); |
if (rc != EOK) { |
block_fini(dev_handle); |
ipc_answer_0(rid, rc); |
return; |
} |
rc = fat_idx_init_by_dev_handle(dev_handle); |
if (rc != EOK) { |
block_fini(dev_handle); |
ipc_answer_0(rid, rc); |
return; |
} |
/* Initialize the root node. */ |
fat_node_t *rootp = (fat_node_t *)malloc(sizeof(fat_node_t)); |
if (!rootp) { |
block_fini(dev_handle); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
fat_node_initialize(rootp); |
fat_idx_t *ridxp = fat_idx_get_by_pos(dev_handle, FAT_CLST_ROOTPAR, 0); |
if (!ridxp) { |
block_fini(dev_handle); |
free(rootp); |
fat_idx_fini_by_dev_handle(dev_handle); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
assert(ridxp->index == 0); |
/* ridxp->lock held */ |
rootp->type = FAT_DIRECTORY; |
rootp->firstc = FAT_CLST_ROOT; |
rootp->refcnt = 1; |
rootp->lnkcnt = 0; /* FS root is not linked */ |
rootp->size = rde * sizeof(fat_dentry_t); |
rootp->idx = ridxp; |
ridxp->nodep = rootp; |
futex_up(&ridxp->lock); |
ipc_answer_3(rid, EOK, ridxp->index, rootp->size, rootp->lnkcnt); |
} |
void fat_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
ipc_answer_0(rid, ENOTSUP); |
} |
void fat_lookup(ipc_callid_t rid, ipc_call_t *request) |
{ |
libfs_lookup(&fat_libfs_ops, fat_reg.fs_handle, rid, request); |
} |
void fat_read(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
off_t pos = (off_t)IPC_GET_ARG3(*request); |
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
fat_bs_t *bs; |
uint16_t bps; |
size_t bytes; |
block_t *b; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
ipc_callid_t callid; |
size_t len; |
if (!ipc_data_read_receive(&callid, &len)) { |
fat_node_put(nodep); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
if (nodep->type == FAT_FILE) { |
/* |
* Our strategy for regular file reads is to read one block at |
* most and make use of the possibility to return less data than |
* requested. This keeps the code very simple. |
*/ |
if (pos >= nodep->size) { |
/* reading beyond the EOF */ |
bytes = 0; |
(void) ipc_data_read_finalize(callid, NULL, 0); |
} else { |
bytes = min(len, bps - pos % bps); |
bytes = min(bytes, nodep->size - pos); |
b = fat_block_get(bs, nodep, pos / bps, |
BLOCK_FLAGS_NONE); |
(void) ipc_data_read_finalize(callid, b->data + pos % bps, |
bytes); |
block_put(b); |
} |
} else { |
unsigned bnum; |
off_t spos = pos; |
char name[FAT_NAME_LEN + 1 + FAT_EXT_LEN + 1]; |
fat_dentry_t *d; |
assert(nodep->type == FAT_DIRECTORY); |
assert(nodep->size % bps == 0); |
assert(bps % sizeof(fat_dentry_t) == 0); |
/* |
* Our strategy for readdir() is to use the position pointer as |
* an index into the array of all dentries. On entry, it points |
* to the first unread dentry. If we skip any dentries, we bump |
* the position pointer accordingly. |
*/ |
bnum = (pos * sizeof(fat_dentry_t)) / bps; |
while (bnum < nodep->size / bps) { |
off_t o; |
b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE); |
for (o = pos % (bps / sizeof(fat_dentry_t)); |
o < bps / sizeof(fat_dentry_t); |
o++, pos++) { |
d = ((fat_dentry_t *)b->data) + o; |
switch (fat_classify_dentry(d)) { |
case FAT_DENTRY_SKIP: |
case FAT_DENTRY_FREE: |
continue; |
case FAT_DENTRY_LAST: |
block_put(b); |
goto miss; |
default: |
case FAT_DENTRY_VALID: |
fat_dentry_name_get(d, name); |
block_put(b); |
goto hit; |
} |
} |
block_put(b); |
bnum++; |
} |
miss: |
fat_node_put(nodep); |
ipc_answer_0(callid, ENOENT); |
ipc_answer_1(rid, ENOENT, 0); |
return; |
hit: |
(void) ipc_data_read_finalize(callid, name, strlen(name) + 1); |
bytes = (pos - spos) + 1; |
} |
fat_node_put(nodep); |
ipc_answer_1(rid, EOK, (ipcarg_t)bytes); |
} |
void fat_write(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
off_t pos = (off_t)IPC_GET_ARG3(*request); |
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
fat_bs_t *bs; |
size_t bytes; |
block_t *b; |
uint16_t bps; |
unsigned spc; |
unsigned bpc; /* bytes per cluster */ |
off_t boundary; |
int flags = BLOCK_FLAGS_NONE; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
ipc_callid_t callid; |
size_t len; |
if (!ipc_data_write_receive(&callid, &len)) { |
fat_node_put(nodep); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
bpc = bps * spc; |
/* |
* In all scenarios, we will attempt to write out only one block worth |
* of data at maximum. There might be some more efficient approaches, |
* but this one greatly simplifies fat_write(). Note that we can afford |
* to do this because the client must be ready to handle the return |
* value signalizing a smaller number of bytes written. |
*/ |
bytes = min(len, bps - pos % bps); |
if (bytes == bps) |
flags |= BLOCK_FLAGS_NOREAD; |
boundary = ROUND_UP(nodep->size, bpc); |
if (pos < boundary) { |
/* |
* This is the easier case - we are either overwriting already |
* existing contents or writing behind the EOF, but still within |
* the limits of the last cluster. The node size may grow to the |
* next block size boundary. |
*/ |
fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); |
b = fat_block_get(bs, nodep, pos / bps, flags); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
if (pos + bytes > nodep->size) { |
nodep->size = pos + bytes; |
nodep->dirty = true; /* need to sync node */ |
} |
ipc_answer_2(rid, EOK, bytes, nodep->size); |
fat_node_put(nodep); |
return; |
} else { |
/* |
* This is the more difficult case. We must allocate new |
* clusters for the node and zero them out. |
*/ |
int status; |
unsigned nclsts; |
fat_cluster_t mcl, lcl; |
nclsts = (ROUND_UP(pos + bytes, bpc) - boundary) / bpc; |
/* create an independent chain of nclsts clusters in all FATs */ |
status = fat_alloc_clusters(bs, dev_handle, nclsts, &mcl, &lcl); |
if (status != EOK) { |
/* could not allocate a chain of nclsts clusters */ |
fat_node_put(nodep); |
ipc_answer_0(callid, status); |
ipc_answer_0(rid, status); |
return; |
} |
/* zero fill any gaps */ |
fat_fill_gap(bs, nodep, mcl, pos); |
b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc, |
flags); |
(void) ipc_data_write_finalize(callid, b->data + pos % bps, |
bytes); |
b->dirty = true; /* need to sync block */ |
block_put(b); |
/* |
* Append the cluster chain starting in mcl to the end of the |
* node's cluster chain. |
*/ |
fat_append_clusters(bs, nodep, mcl); |
nodep->size = pos + bytes; |
nodep->dirty = true; /* need to sync node */ |
ipc_answer_2(rid, EOK, bytes, nodep->size); |
fat_node_put(nodep); |
return; |
} |
} |
void fat_truncate(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
size_t size = (off_t)IPC_GET_ARG3(*request); |
fat_node_t *nodep = (fat_node_t *)fat_node_get(dev_handle, index); |
fat_bs_t *bs; |
uint16_t bps; |
uint8_t spc; |
unsigned bpc; /* bytes per cluster */ |
int rc; |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
bs = block_bb_get(dev_handle); |
bps = uint16_t_le2host(bs->bps); |
spc = bs->spc; |
bpc = bps * spc; |
if (nodep->size == size) { |
rc = EOK; |
} else if (nodep->size < size) { |
/* |
* The standard says we have the freedom to grow the node. |
* For now, we simply return an error. |
*/ |
rc = EINVAL; |
} else if (ROUND_UP(nodep->size, bpc) == ROUND_UP(size, bpc)) { |
/* |
* The node will be shrunk, but no clusters will be deallocated. |
*/ |
nodep->size = size; |
nodep->dirty = true; /* need to sync node */ |
rc = EOK; |
} else { |
/* |
* The node will be shrunk, clusters will be deallocated. |
*/ |
if (size == 0) { |
fat_chop_clusters(bs, nodep, FAT_CLST_RES0); |
} else { |
fat_cluster_t lastc; |
(void) fat_cluster_walk(bs, dev_handle, nodep->firstc, |
&lastc, (size - 1) / bpc); |
fat_chop_clusters(bs, nodep, lastc); |
} |
nodep->size = size; |
nodep->dirty = true; /* need to sync node */ |
rc = EOK; |
} |
fat_node_put(nodep); |
ipc_answer_0(rid, rc); |
return; |
} |
void fat_destroy(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
fs_index_t index = (fs_index_t)IPC_GET_ARG2(*request); |
int rc; |
fat_node_t *nodep = fat_node_get(dev_handle, index); |
if (!nodep) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
rc = fat_destroy_node(nodep); |
ipc_answer_0(rid, rc); |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/fs/fat/fat_idx.c |
---|
74,32 → 74,6 |
/** List of unused structures. */ |
static LIST_INITIALIZE(unused_head); |
static void unused_initialize(unused_t *u, dev_handle_t dev_handle) |
{ |
link_initialize(&u->link); |
u->dev_handle = dev_handle; |
u->next = 0; |
u->remaining = ((uint64_t)((fs_index_t)-1)) + 1; |
list_initialize(&u->freed_head); |
} |
static unused_t *unused_find(dev_handle_t dev_handle, bool lock) |
{ |
unused_t *u; |
link_t *l; |
if (lock) |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
return u; |
} |
if (lock) |
futex_up(&unused_futex); |
return NULL; |
} |
/** Futex protecting the up_hash and ui_hash. */ |
static futex_t used_futex = FUTEX_INITIALIZER; |
214,15 → 188,24 |
}; |
/** Allocate a VFS index which is not currently in use. */ |
static bool fat_index_alloc(dev_handle_t dev_handle, fs_index_t *index) |
static bool fat_idx_alloc(dev_handle_t dev_handle, fs_index_t *index) |
{ |
link_t *l; |
unused_t *u; |
assert(index); |
u = unused_find(dev_handle, true); |
if (!u) |
return false; |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
goto hit; |
} |
futex_up(&unused_futex); |
/* dev_handle not found */ |
return false; |
hit: |
if (list_empty(&u->freed_head)) { |
if (u->remaining) { |
/* |
276,13 → 259,23 |
} |
/** Free a VFS index, which is no longer in use. */ |
static void fat_index_free(dev_handle_t dev_handle, fs_index_t index) |
static void fat_idx_free(dev_handle_t dev_handle, fs_index_t index) |
{ |
link_t *l; |
unused_t *u; |
u = unused_find(dev_handle, true); |
assert(u); |
futex_down(&unused_futex); |
for (l = unused_head.next; l != &unused_head; l = l->next) { |
u = list_get_instance(l, unused_t, link); |
if (u->dev_handle == dev_handle) |
goto hit; |
} |
futex_up(&unused_futex); |
/* should not happen */ |
assert(0); |
hit: |
if (u->next == index + 1) { |
/* The index can be returned directly to the counter. */ |
u->next--; |
338,52 → 331,6 |
futex_up(&unused_futex); |
} |
static fat_idx_t *fat_idx_create(dev_handle_t dev_handle) |
{ |
fat_idx_t *fidx; |
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); |
if (!fidx) |
return NULL; |
if (!fat_index_alloc(dev_handle, &fidx->index)) { |
free(fidx); |
return NULL; |
} |
link_initialize(&fidx->uph_link); |
link_initialize(&fidx->uih_link); |
futex_initialize(&fidx->lock, 1); |
fidx->dev_handle = dev_handle; |
fidx->pfc = FAT_CLST_RES0; /* no parent yet */ |
fidx->pdi = 0; |
fidx->nodep = NULL; |
return fidx; |
} |
fat_idx_t *fat_idx_get_new(dev_handle_t dev_handle) |
{ |
fat_idx_t *fidx; |
futex_down(&used_futex); |
fidx = fat_idx_create(dev_handle); |
if (!fidx) { |
futex_up(&used_futex); |
return NULL; |
} |
unsigned long ikey[] = { |
[UIH_DH_KEY] = dev_handle, |
[UIH_INDEX_KEY] = fidx->index, |
}; |
hash_table_insert(&ui_hash, ikey, &fidx->uih_link); |
futex_down(&fidx->lock); |
futex_up(&used_futex); |
return fidx; |
} |
fat_idx_t * |
fat_idx_get_by_pos(dev_handle_t dev_handle, fat_cluster_t pfc, unsigned pdi) |
{ |
400,11 → 347,16 |
if (l) { |
fidx = hash_table_get_instance(l, fat_idx_t, uph_link); |
} else { |
fidx = fat_idx_create(dev_handle); |
fidx = (fat_idx_t *) malloc(sizeof(fat_idx_t)); |
if (!fidx) { |
futex_up(&used_futex); |
return NULL; |
} |
if (!fat_idx_alloc(dev_handle, &fidx->index)) { |
free(fidx); |
futex_up(&used_futex); |
return NULL; |
} |
unsigned long ikey[] = { |
[UIH_DH_KEY] = dev_handle, |
411,8 → 363,13 |
[UIH_INDEX_KEY] = fidx->index, |
}; |
link_initialize(&fidx->uph_link); |
link_initialize(&fidx->uih_link); |
futex_initialize(&fidx->lock, 1); |
fidx->dev_handle = dev_handle; |
fidx->pfc = pfc; |
fidx->pdi = pdi; |
fidx->nodep = NULL; |
hash_table_insert(&up_hash, pkey, &fidx->uph_link); |
hash_table_insert(&ui_hash, ikey, &fidx->uih_link); |
423,32 → 380,6 |
return fidx; |
} |
void fat_idx_hashin(fat_idx_t *idx) |
{ |
unsigned long pkey[] = { |
[UPH_DH_KEY] = idx->dev_handle, |
[UPH_PFC_KEY] = idx->pfc, |
[UPH_PDI_KEY] = idx->pdi, |
}; |
futex_down(&used_futex); |
hash_table_insert(&up_hash, pkey, &idx->uph_link); |
futex_up(&used_futex); |
} |
void fat_idx_hashout(fat_idx_t *idx) |
{ |
unsigned long pkey[] = { |
[UPH_DH_KEY] = idx->dev_handle, |
[UPH_PFC_KEY] = idx->pfc, |
[UPH_PDI_KEY] = idx->pdi, |
}; |
futex_down(&used_futex); |
hash_table_remove(&up_hash, pkey, 3); |
futex_up(&used_futex); |
} |
fat_idx_t * |
fat_idx_get_by_index(dev_handle_t dev_handle, fs_index_t index) |
{ |
470,87 → 401,3 |
return fidx; |
} |
/** Destroy the index structure. |
* |
* @param idx The index structure to be destroyed. |
*/ |
void fat_idx_destroy(fat_idx_t *idx) |
{ |
unsigned long ikey[] = { |
[UIH_DH_KEY] = idx->dev_handle, |
[UIH_INDEX_KEY] = idx->index, |
}; |
assert(idx->pfc == FAT_CLST_RES0); |
futex_down(&used_futex); |
/* |
* Since we can only free unlinked nodes, the index structure is not |
* present in the position hash (uph). We therefore hash it out from |
* the index hash only. |
*/ |
hash_table_remove(&ui_hash, ikey, 2); |
futex_up(&used_futex); |
/* Release the VFS index. */ |
fat_index_free(idx->dev_handle, idx->index); |
/* Deallocate the structure. */ |
free(idx); |
} |
int fat_idx_init(void) |
{ |
if (!hash_table_create(&up_hash, UPH_BUCKETS, 3, &uph_ops)) |
return ENOMEM; |
if (!hash_table_create(&ui_hash, UIH_BUCKETS, 2, &uih_ops)) { |
hash_table_destroy(&up_hash); |
return ENOMEM; |
} |
return EOK; |
} |
void fat_idx_fini(void) |
{ |
/* We assume the hash tables are empty. */ |
hash_table_destroy(&up_hash); |
hash_table_destroy(&ui_hash); |
} |
int fat_idx_init_by_dev_handle(dev_handle_t dev_handle) |
{ |
unused_t *u; |
int rc = EOK; |
u = (unused_t *) malloc(sizeof(unused_t)); |
if (!u) |
return ENOMEM; |
unused_initialize(u, dev_handle); |
futex_down(&unused_futex); |
if (!unused_find(dev_handle, false)) |
list_append(&u->link, &unused_head); |
else |
rc = EEXIST; |
futex_up(&unused_futex); |
return rc; |
} |
void fat_idx_fini_by_dev_handle(dev_handle_t dev_handle) |
{ |
unused_t *u; |
u = unused_find(dev_handle, true); |
assert(u); |
list_remove(&u->link); |
futex_up(&unused_futex); |
while (!list_empty(&u->freed_head)) { |
freed_t *f; |
f = list_get_instance(u->freed_head.next, freed_t, link); |
list_remove(&f->link); |
free(f); |
} |
free(u); |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/fs/fat/fat.h |
---|
33,7 → 33,6 |
#ifndef FAT_FAT_H_ |
#define FAT_FAT_H_ |
#include "fat_fat.h" |
#include <ipc/ipc.h> |
#include <libfs.h> |
#include <atomic.h> |
41,16 → 40,9 |
#include <bool.h> |
#include "../../vfs/vfs.h" |
#ifndef dprintf |
#define dprintf(...) printf(__VA_ARGS__) |
#endif |
#define min(a, b) ((a) < (b) ? (a) : (b)) |
#define BS_BLOCK 0 |
#define BS_SIZE 512 |
typedef struct fat_bs { |
typedef struct { |
uint8_t ji[3]; /**< Jump instruction. */ |
uint8_t oem_name[8]; |
/* BIOS Parameter Block */ |
121,6 → 113,34 |
}; |
} __attribute__ ((packed)) fat_bs_t; |
#define FAT_ATTR_RDONLY (1 << 0) |
#define FAT_ATTR_VOLLABEL (1 << 3) |
#define FAT_ATTR_SUBDIR (1 << 4) |
typedef struct { |
uint8_t name[8]; |
uint8_t ext[3]; |
uint8_t attr; |
uint8_t reserved; |
uint8_t ctime_fine; |
uint16_t ctime; |
uint16_t cdate; |
uint16_t adate; |
union { |
uint16_t eaidx; /* FAT12/FAT16 */ |
uint16_t firstc_hi; /* FAT32 */ |
}; |
uint16_t mtime; |
uint16_t mdate; |
union { |
uint16_t firstc; /* FAT12/FAT16 */ |
uint16_t firstc_lo; /* FAT32 */ |
}; |
uint32_t size; |
} __attribute__ ((packed)) fat_dentry_t; |
typedef uint16_t fat_cluster_t; |
typedef enum { |
FAT_INVALID, |
FAT_DIRECTORY, |
197,26 → 217,11 |
extern fs_reg_t fat_reg; |
extern void fat_mounted(ipc_callid_t, ipc_call_t *); |
extern void fat_mount(ipc_callid_t, ipc_call_t *); |
extern void fat_lookup(ipc_callid_t, ipc_call_t *); |
extern void fat_read(ipc_callid_t, ipc_call_t *); |
extern void fat_write(ipc_callid_t, ipc_call_t *); |
extern void fat_truncate(ipc_callid_t, ipc_call_t *); |
extern void fat_destroy(ipc_callid_t, ipc_call_t *); |
extern fat_idx_t *fat_idx_get_new(dev_handle_t); |
extern fat_idx_t *fat_idx_get_by_pos(dev_handle_t, fat_cluster_t, unsigned); |
extern fat_idx_t *fat_idx_get_by_index(dev_handle_t, fs_index_t); |
extern void fat_idx_destroy(fat_idx_t *); |
extern void fat_idx_hashin(fat_idx_t *); |
extern void fat_idx_hashout(fat_idx_t *); |
extern int fat_idx_init(void); |
extern void fat_idx_fini(void); |
extern int fat_idx_init_by_dev_handle(dev_handle_t); |
extern void fat_idx_fini_by_dev_handle(dev_handle_t); |
#endif |
/** |
/branches/dd/uspace/srv/fs/fat/Makefile |
---|
31,17 → 31,12 |
LIBC_PREFIX = ../../../lib/libc |
LIBFS_PREFIX = ../../../lib/libfs |
LIBBLOCK_PREFIX = ../../../lib/libblock |
SOFTINT_PREFIX = ../../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I $(LIBFS_PREFIX) -I $(LIBBLOCK_PREFIX) |
CFLAGS += -I $(LIBFS_PREFIX) |
LIBS = \ |
$(LIBFS_PREFIX)/libfs.a \ |
$(LIBBLOCK_PREFIX)/libblock.a \ |
$(LIBC_PREFIX)/libc.a |
LIBS = $(LIBC_PREFIX)/libc.a $(LIBFS_PREFIX)/libfs.a |
## Sources |
# |
50,32 → 45,28 |
SOURCES = \ |
fat.c \ |
fat_ops.c \ |
fat_idx.c \ |
fat_dentry.c \ |
fat_fat.c |
fat_idx.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/fs/fat/fat.c |
---|
49,6 → 49,14 |
vfs_info_t fat_vfs_info = { |
.name = "fat", |
.ops = { |
[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_READ)] = VFS_OP_DEFINED, |
[IPC_METHOD_TO_VFS_OP(VFS_WRITE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_TRUNCATE)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_MOUNT)] = VFS_OP_NULL, |
[IPC_METHOD_TO_VFS_OP(VFS_UNMOUNT)] = VFS_OP_NULL, |
} |
}; |
fs_reg_t fat_reg; |
89,27 → 97,9 |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case VFS_MOUNTED: |
fat_mounted(callid, &call); |
break; |
case VFS_MOUNT: |
fat_mount(callid, &call); |
break; |
case VFS_LOOKUP: |
fat_lookup(callid, &call); |
break; |
case VFS_READ: |
fat_read(callid, &call); |
break; |
case VFS_WRITE: |
fat_write(callid, &call); |
break; |
case VFS_TRUNCATE: |
fat_truncate(callid, &call); |
break; |
case VFS_DESTROY: |
fat_destroy(callid, &call); |
break; |
default: |
ipc_answer_0(callid, ENOTSUP); |
break; |
120,24 → 110,20 |
int main(int argc, char **argv) |
{ |
int vfs_phone; |
int rc; |
printf("fat: HelenOS FAT file system server.\n"); |
printf("FAT: HelenOS FAT file system server.\n"); |
rc = fat_idx_init(); |
if (rc != EOK) |
goto err; |
vfs_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VFS, 0, 0); |
if (vfs_phone < EOK) { |
printf("fat: failed to connect to VFS\n"); |
return -1; |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
while (vfs_phone < EOK) { |
usleep(10000); |
vfs_phone = ipc_connect_me_to(PHONE_NS, SERVICE_VFS, 0, 0); |
} |
int rc; |
rc = fs_register(vfs_phone, &fat_reg, &fat_vfs_info, fat_connection); |
if (rc != EOK) { |
fat_idx_fini(); |
goto err; |
printf("Failed to register the FAT file system (%d)\n", rc); |
return rc; |
} |
dprintf("FAT filesystem registered, fs_handle=%d.\n", |
146,10 → 132,6 |
async_manager(); |
/* not reached */ |
return 0; |
err: |
printf("Failed to register the FAT file system (%d)\n", rc); |
return rc; |
} |
/** |
/branches/dd/uspace/srv/vfs/vfs_ops.c |
---|
28,11 → 28,11 |
/** @addtogroup fs |
* @{ |
*/ |
*/ |
/** |
* @file vfs_ops.c |
* @brief Operations that VFS offers to its clients. |
* @file vfs_ops.c |
* @brief Operations that VFS offers to its clients. |
*/ |
#include "vfs.h" |
55,18 → 55,6 |
/* Forward declarations of static functions. */ |
static int vfs_truncate_internal(fs_handle_t, dev_handle_t, fs_index_t, size_t); |
/** Pending mount structure. */ |
typedef struct { |
link_t link; |
char *fs_name; /**< File system name */ |
char *mp; /**< Mount point */ |
ipc_callid_t callid; /**< Call ID waiting for the mount */ |
ipc_callid_t rid; /**< Request ID */ |
dev_handle_t dev_handle; /**< Device handle */ |
} pending_req_t; |
LIST_INITIALIZE(pending_req); |
/** |
* This rwlock prevents the race between a triplet-to-VFS-node resolution and a |
* concurrent VFS operation which modifies the file system namespace. |
74,48 → 62,161 |
RWLOCK_INITIALIZE(namespace_rwlock); |
futex_t rootfs_futex = FUTEX_INITIALIZER; |
vfs_pair_t rootfs = { |
vfs_triplet_t rootfs = { |
.fs_handle = 0, |
.dev_handle = 0 |
.dev_handle = 0, |
.index = 0, |
}; |
static void vfs_mount_internal(ipc_callid_t rid, dev_handle_t dev_handle, |
fs_handle_t fs_handle, char *mp) |
static int |
lookup_root(fs_handle_t fs_handle, dev_handle_t dev_handle, |
vfs_lookup_res_t *result) |
{ |
/* Resolve the path to the mountpoint. */ |
vfs_lookup_res_t mp_res; |
vfs_pair_t altroot = { |
.fs_handle = fs_handle, |
.dev_handle = dev_handle, |
}; |
return vfs_lookup_internal("/", L_DIRECTORY, result, &altroot); |
} |
void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
dev_handle_t dev_handle; |
vfs_node_t *mp_node = NULL; |
int rc; |
int phone; |
/* |
* We expect the library to do the device-name to device-handle |
* translation for us, thus the device handle will arrive as ARG1 |
* in the request. |
*/ |
dev_handle = (dev_handle_t)IPC_GET_ARG1(*request); |
/* |
* For now, don't make use of ARG2 and ARG3, but they can be used to |
* carry mount options in the future. |
*/ |
ipc_callid_t callid; |
size_t size; |
/* |
* Now, we expect the client to send us data with the name of the file |
* system. |
*/ |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* |
* Don't receive more than is necessary for storing a full file system |
* name. |
*/ |
if (size < 1 || size > FS_NAME_MAXLEN) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* Deliver the file system name. */ |
char fs_name[FS_NAME_MAXLEN + 1]; |
(void) ipc_data_write_finalize(callid, fs_name, size); |
fs_name[size] = '\0'; |
/* |
* Check if we know a file system with the same name as is in fs_name. |
* This will also give us its file system handle. |
*/ |
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
if (!fs_handle) { |
ipc_answer_0(rid, ENOENT); |
return; |
} |
/* Now, we want the client to send us the mount point. */ |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* Check whether size is reasonable wrt. the mount point. */ |
if (size < 1 || size > MAX_PATH_LEN) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* Allocate buffer for the mount point data being received. */ |
uint8_t *buf; |
buf = malloc(size + 1); |
if (!buf) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
/* Deliver the mount point. */ |
(void) ipc_data_write_finalize(callid, buf, size); |
buf[size] = '\0'; |
/* |
* Lookup the root node of the filesystem being mounted. |
* In this case, we don't need to take the namespace_futex as the root |
* node cannot be removed. However, we do take a reference to it so |
* that we can track how many times it has been mounted. |
*/ |
vfs_lookup_res_t mr_res; |
rc = lookup_root(fs_handle, dev_handle, &mr_res); |
if (rc != EOK) { |
free(buf); |
ipc_answer_0(rid, rc); |
return; |
} |
vfs_node_t *mr_node = vfs_node_get(&mr_res); |
if (!mr_node) { |
free(buf); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
/* Finally, we need to resolve the path to the mountpoint. */ |
vfs_lookup_res_t mp_res; |
futex_down(&rootfs_futex); |
if (rootfs.fs_handle) { |
/* We already have the root FS. */ |
rwlock_write_lock(&namespace_rwlock); |
if ((strlen(mp) == 1) && (mp[0] == '/')) { |
if ((size == 1) && (buf[0] == '/')) { |
/* Trying to mount root FS over root FS */ |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); |
free(buf); |
ipc_answer_0(rid, EBUSY); |
return; |
} |
rc = vfs_lookup_internal(mp, L_DIRECTORY, &mp_res, NULL); |
rc = vfs_lookup_internal(buf, L_DIRECTORY, &mp_res, NULL); |
if (rc != EOK) { |
/* The lookup failed for some reason. */ |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
free(buf); |
ipc_answer_0(rid, rc); |
return; |
} |
mp_node = vfs_node_get(&mp_res); |
if (!mp_node) { |
rwlock_write_unlock(&namespace_rwlock); |
futex_up(&rootfs_futex); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
free(buf); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
/* |
* Now we hold a reference to mp_node. |
* It will be dropped upon the corresponding VFS_UNMOUNT. |
124,45 → 225,29 |
rwlock_write_unlock(&namespace_rwlock); |
} else { |
/* We still don't have the root file system mounted. */ |
if ((strlen(mp) == 1) && (mp[0] == '/')) { |
vfs_lookup_res_t mr_res; |
vfs_node_t *mr_node; |
ipcarg_t rindex; |
ipcarg_t rsize; |
ipcarg_t rlnkcnt; |
if ((size == 1) && (buf[0] == '/')) { |
/* |
* For this simple, but important case, |
* we are almost done. |
*/ |
free(buf); |
/* Tell the mountee that it is being mounted. */ |
phone = vfs_grab_phone(fs_handle); |
rc = async_req_1_3(phone, VFS_MOUNTED, |
(ipcarg_t) dev_handle, &rindex, &rsize, &rlnkcnt); |
/* Inform the mount point about the root mount. */ |
phone = vfs_grab_phone(mr_res.triplet.fs_handle); |
rc = async_req_5_0(phone, VFS_MOUNT, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index, |
(ipcarg_t) mr_res.triplet.fs_handle, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index); |
vfs_release_phone(phone); |
if (rc != EOK) { |
futex_up(&rootfs_futex); |
ipc_answer_0(rid, rc); |
return; |
} |
mr_res.triplet.fs_handle = fs_handle; |
mr_res.triplet.dev_handle = dev_handle; |
mr_res.triplet.index = (fs_index_t) rindex; |
mr_res.size = (size_t) rsize; |
mr_res.lnkcnt = (unsigned) rlnkcnt; |
mr_res.type = VFS_NODE_DIRECTORY; |
rootfs.fs_handle = fs_handle; |
rootfs.dev_handle = dev_handle; |
if (rc == EOK) |
rootfs = mr_res.triplet; |
else |
vfs_node_put(mr_node); |
futex_up(&rootfs_futex); |
/* Add reference to the mounted root. */ |
mr_node = vfs_node_get(&mr_res); |
assert(mr_node); |
ipc_answer_0(rid, rc); |
return; |
} else { |
171,6 → 256,8 |
* being mounted first. |
*/ |
futex_up(&rootfs_futex); |
free(buf); |
vfs_node_put(mr_node); /* failed -> drop reference */ |
ipc_answer_0(rid, ENOENT); |
return; |
} |
177,21 → 264,30 |
} |
futex_up(&rootfs_futex); |
free(buf); /* The buffer is not needed anymore. */ |
/* |
* At this point, we have all necessary pieces: file system and device |
* handles, and we know the mount point VFS node. |
* handles, and we know the mount point VFS node and also the root node |
* of the file system being mounted. |
*/ |
/** |
* @todo |
* Add more IPC parameters so that we can send mount mode/flags. |
*/ |
phone = vfs_grab_phone(mp_res.triplet.fs_handle); |
rc = async_req_4_0(phone, VFS_MOUNT, |
rc = async_req_5_0(phone, VFS_MOUNT, |
(ipcarg_t) mp_res.triplet.dev_handle, |
(ipcarg_t) mp_res.triplet.index, |
(ipcarg_t) fs_handle, |
(ipcarg_t) dev_handle); |
(ipcarg_t) mr_res.triplet.fs_handle, |
(ipcarg_t) mr_res.triplet.dev_handle, |
(ipcarg_t) mr_res.triplet.index); |
vfs_release_phone(phone); |
if (rc != EOK) { |
/* Mount failed, drop reference to mp_node. */ |
/* Mount failed, drop references to mr_node and mp_node. */ |
vfs_node_put(mr_node); |
if (mp_node) |
vfs_node_put(mp_node); |
} |
199,170 → 295,6 |
ipc_answer_0(rid, rc); |
} |
/** Process pending mount requests */ |
void vfs_process_pending_mount() |
{ |
link_t *cur; |
loop: |
for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
fs_handle_t fs_handle = fs_name_to_handle(pr->fs_name, true); |
if (!fs_handle) |
continue; |
/* Acknowledge that we know fs_name. */ |
ipc_answer_0(pr->callid, EOK); |
/* Do the mount */ |
vfs_mount_internal(pr->rid, pr->dev_handle, fs_handle, pr->mp); |
free(pr->fs_name); |
free(pr->mp); |
list_remove(cur); |
free(pr); |
goto loop; |
} |
} |
void vfs_mount(ipc_callid_t rid, ipc_call_t *request) |
{ |
/* |
* We expect the library to do the device-name to device-handle |
* translation for us, thus the device handle will arrive as ARG1 |
* in the request. |
*/ |
dev_handle_t dev_handle = (dev_handle_t) IPC_GET_ARG1(*request); |
/* |
* Mount flags are passed as ARG2. |
*/ |
unsigned int flags = (unsigned int) IPC_GET_ARG2(*request); |
/* |
* For now, don't make use of ARG3, but it can be used to |
* carry mount options in the future. |
*/ |
/* We want the client to send us the mount point. */ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* Check whether size is reasonable wrt. the mount point. */ |
if ((size < 1) || (size > MAX_PATH_LEN)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* Allocate buffer for the mount point data being received. */ |
char *mp = malloc(size + 1); |
if (!mp) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
return; |
} |
/* Deliver the mount point. */ |
ipcarg_t retval = ipc_data_write_finalize(callid, mp, size); |
if (retval != EOK) { |
ipc_answer_0(rid, EREFUSED); |
free(mp); |
return; |
} |
mp[size] = '\0'; |
/* |
* Now, we expect the client to send us data with the name of the file |
* system. |
*/ |
if (!ipc_data_write_receive(&callid, &size)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
free(mp); |
return; |
} |
/* |
* Don't receive more than is necessary for storing a full file system |
* name. |
*/ |
if ((size < 1) || (size > FS_NAME_MAXLEN)) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(rid, EINVAL); |
free(mp); |
return; |
} |
/* |
* Allocate buffer for file system name. |
*/ |
char *fs_name = (char *) malloc(size + 1); |
if (fs_name == NULL) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, EREFUSED); |
free(mp); |
return; |
} |
/* Deliver the file system name. */ |
retval = ipc_data_write_finalize(callid, fs_name, size); |
if (retval != EOK) { |
ipc_answer_0(rid, EREFUSED); |
free(mp); |
free(fs_name); |
return; |
} |
fs_name[size] = '\0'; |
/* |
* Check if we know a file system with the same name as is in fs_name. |
* This will also give us its file system handle. |
*/ |
fs_handle_t fs_handle = fs_name_to_handle(fs_name, true); |
if (!fs_handle) { |
if (flags & IPC_FLAG_BLOCKING) { |
/* Blocking mount, add to pending list */ |
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
if (!pr) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(rid, ENOMEM); |
free(mp); |
free(fs_name); |
return; |
} |
pr->fs_name = fs_name; |
pr->mp = mp; |
pr->callid = callid; |
pr->rid = rid; |
pr->dev_handle = dev_handle; |
list_append(&pr->link, &pending_req); |
return; |
} |
ipc_answer_0(callid, ENOENT); |
ipc_answer_0(rid, ENOENT); |
free(mp); |
free(fs_name); |
return; |
} |
/* Acknowledge that we know fs_name. */ |
ipc_answer_0(callid, EOK); |
/* Do the mount */ |
vfs_mount_internal(rid, dev_handle, fs_handle, mp); |
free(mp); |
free(fs_name); |
} |
void vfs_open(ipc_callid_t rid, ipc_call_t *request) |
{ |
if (!vfs_files_init()) { |
383,16 → 315,6 |
int mode = IPC_GET_ARG3(*request); |
size_t len; |
/* |
* Make sure that we are called with exactly one of L_FILE and |
* L_DIRECTORY. |
*/ |
if ((lflag & (L_FILE | L_DIRECTORY)) == 0 || |
(lflag & (L_FILE | L_DIRECTORY)) == (L_FILE | L_DIRECTORY)) { |
ipc_answer_0(rid, EINVAL); |
return; |
} |
if (oflag & O_CREAT) |
lflag |= L_CREATE; |
if (oflag & O_EXCL) |
500,8 → 422,12 |
void vfs_close(ipc_callid_t rid, ipc_call_t *request) |
{ |
int fd = IPC_GET_ARG1(*request); |
int rc = vfs_fd_free(fd); |
ipc_answer_0(rid, rc); |
if (fd >= MAX_OPEN_FILES) { |
ipc_answer_0(rid, EBADF); |
return; |
} |
vfs_fd_free(fd); |
ipc_answer_0(rid, EOK); |
} |
static void vfs_rdwr(ipc_callid_t rid, ipc_call_t *request, bool read) |
518,7 → 444,7 |
*/ |
int fd = IPC_GET_ARG1(*request); |
/* Lookup the file structure corresponding to the file descriptor. */ |
vfs_file_t *file = vfs_file_get(fd); |
if (!file) { |
525,7 → 451,7 |
ipc_answer_0(rid, ENOENT); |
return; |
} |
/* |
* Now we need to receive a call with client's |
* IPC_M_DATA_READ/IPC_M_DATA_WRITE request. |
541,7 → 467,7 |
ipc_answer_0(rid, EINVAL); |
return; |
} |
/* |
* Lock the open file structure so that no other thread can manipulate |
* the same open file at a time. |
557,15 → 483,6 |
else |
rwlock_write_lock(&file->node->contents_rwlock); |
if (file->node->type == VFS_NODE_DIRECTORY) { |
/* |
* Make sure that no one is modifying the namespace |
* while we are in readdir(). |
*/ |
assert(read); |
rwlock_read_lock(&namespace_rwlock); |
} |
int fs_phone = vfs_grab_phone(file->node->fs_handle); |
/* Make a VFS_READ/VFS_WRITE request at the destination FS server. */ |
583,17 → 500,14 |
* don't have to bother. |
*/ |
ipc_forward_fast(callid, fs_phone, 0, 0, 0, IPC_FF_ROUTE_FROM_ME); |
vfs_release_phone(fs_phone); |
/* Wait for reply from the FS server. */ |
ipcarg_t rc; |
async_wait_for(msg, &rc); |
size_t bytes = IPC_GET_ARG1(answer); |
if (file->node->type == VFS_NODE_DIRECTORY) |
rwlock_read_unlock(&namespace_rwlock); |
/* Unlock the VFS node. */ |
if (read) |
rwlock_read_unlock(&file->node->contents_rwlock); |
603,12 → 517,12 |
file->node->size = IPC_GET_ARG2(answer); |
rwlock_write_unlock(&file->node->contents_rwlock); |
} |
/* Update the position pointer and unlock the open file. */ |
if (rc == EOK) |
file->pos += bytes; |
futex_up(&file->lock); |
/* |
* FS server's reply is the final result of the whole operation we |
* return to the client. |
/branches/dd/uspace/srv/vfs/vfs.h |
---|
40,13 → 40,12 |
#include <sys/types.h> |
#include <bool.h> |
// FIXME: according to CONFIG_DEBUG |
// #define dprintf(...) printf(__VA_ARGS__) |
#define dprintf(...) printf(__VA_ARGS__) |
#define dprintf(...) |
#define VFS_FIRST IPC_FIRST_USER_METHOD |
#define IPC_METHOD_TO_VFS_OP(m) ((m) - VFS_FIRST) |
/* Basic types. */ |
typedef int16_t fs_handle_t; |
typedef int16_t dev_handle_t; |
63,7 → 62,6 |
typedef enum { |
VFS_LOOKUP = VFS_LAST_CMN, |
VFS_MOUNTED, |
VFS_DESTROY, |
VFS_LAST_CLNT, /* keep this the last member of this enum */ |
} vfs_request_clnt_t; |
79,16 → 77,32 |
VFS_LAST_SRV, /* keep this the last member of this enum */ |
} vfs_request_srv_t; |
/** |
* An instance of this structure is associated with a particular FS operation. |
* It tells VFS if the FS supports the operation or maybe if a default one |
* should be used. |
*/ |
typedef enum { |
VFS_OP_NULL = 0, |
VFS_OP_DEFAULT, |
VFS_OP_DEFINED |
} vfs_op_t; |
#define FS_NAME_MAXLEN 20 |
/** |
* A structure like this is passed to VFS by each individual FS upon its |
* registration. It assosiates a human-readable identifier with each |
* registered FS. |
* registered FS. More importantly, through this structure, the FS announces |
* what operations it supports. |
*/ |
typedef struct { |
/** Unique identifier of the fs. */ |
char name[FS_NAME_MAXLEN + 1]; |
/** Operations. */ |
vfs_op_t ops[VFS_LAST_CLNT - VFS_FIRST]; |
} vfs_info_t; |
/** |
172,15 → 186,8 |
*/ |
#define L_PARENT 64 |
typedef enum vfs_node_type { |
VFS_NODE_UNKNOWN, |
VFS_NODE_FILE, |
VFS_NODE_DIRECTORY, |
} vfs_node_type_t; |
typedef struct { |
vfs_triplet_t triplet; |
vfs_node_type_t type; |
size_t size; |
unsigned lnkcnt; |
} vfs_lookup_res_t; |
202,9 → 209,6 |
unsigned lnkcnt; |
link_t nh_link; /**< Node hash-table link. */ |
vfs_node_type_t type; /**< Partial info about the node type. */ |
size_t size; /**< Cached size if the node is a file. */ |
/** |
237,7 → 241,7 |
extern link_t fs_head; /**< List of registered file systems. */ |
extern vfs_pair_t rootfs; /**< Root file system. */ |
extern vfs_triplet_t rootfs; /**< Root node of the root file system. */ |
#define MAX_PATH_LEN (64 * 1024) |
274,7 → 278,7 |
extern bool vfs_files_init(void); |
extern vfs_file_t *vfs_file_get(int); |
extern int vfs_fd_alloc(void); |
extern int vfs_fd_free(int); |
extern void vfs_fd_free(int); |
extern void vfs_file_addref(vfs_file_t *); |
extern void vfs_file_delref(vfs_file_t *); |
282,7 → 286,6 |
extern void vfs_node_addref(vfs_node_t *); |
extern void vfs_node_delref(vfs_node_t *); |
extern void vfs_process_pending_mount(void); |
extern void vfs_register(ipc_callid_t, ipc_call_t *); |
extern void vfs_mount(ipc_callid_t, ipc_call_t *); |
extern void vfs_open(ipc_callid_t, ipc_call_t *); |
/branches/dd/uspace/srv/vfs/vfs_register.c |
---|
28,10 → 28,10 |
/** @addtogroup fs |
* @{ |
*/ |
*/ |
/** |
* @file vfs_register.c |
* @file vfs_register.c |
* @brief |
*/ |
98,6 → 98,30 |
return false; |
} |
/* |
* Check if the FS implements mandatory VFS operations. |
*/ |
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_LOOKUP)] != VFS_OP_DEFINED) { |
dprintf("Operation VFS_LOOKUP not defined by the client.\n"); |
return false; |
} |
if (info->ops[IPC_METHOD_TO_VFS_OP(VFS_READ)] != VFS_OP_DEFINED) { |
dprintf("Operation VFS_READ not defined by the client.\n"); |
return false; |
} |
/* |
* Check if each operation is either not defined, defined or default. |
*/ |
for (i = VFS_FIRST; i < VFS_LAST_CLNT; i++) { |
if ((info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_NULL) && |
(info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFAULT) && |
(info->ops[IPC_METHOD_TO_VFS_OP(i)] != VFS_OP_DEFINED)) { |
dprintf("Operation info not understood.\n"); |
return false; |
} |
} |
return true; |
} |
278,11 → 302,6 |
dprintf("\"%.*s\" filesystem successfully registered, handle=%d.\n", |
FS_NAME_MAXLEN, fs_info->vfs_info.name, fs_info->fs_handle); |
/* Process pending mount requests possibly waiting |
* for this filesystem implementation. |
*/ |
vfs_process_pending_mount(); |
} |
/** For a given file system handle, implement policy for allocating a phone. |
/branches/dd/uspace/srv/vfs/vfs_lookup.c |
---|
72,7 → 72,7 |
if (altroot) |
root = altroot; |
else |
root = &rootfs; |
root = (vfs_pair_t *) &rootfs; |
if (!root->fs_handle) |
return ENOENT; |
182,12 → 182,6 |
result->triplet.index = (fs_index_t) IPC_GET_ARG3(answer); |
result->size = (size_t) IPC_GET_ARG4(answer); |
result->lnkcnt = (unsigned) IPC_GET_ARG5(answer); |
if (lflag & L_FILE) |
result->type = VFS_NODE_FILE; |
else if (lflag & L_DIRECTORY) |
result->type = VFS_NODE_DIRECTORY; |
else |
result->type = VFS_NODE_UNKNOWN; |
} |
return rc; |
/branches/dd/uspace/srv/vfs/vfs_node.c |
---|
175,22 → 175,15 |
node->index = result->triplet.index; |
node->size = result->size; |
node->lnkcnt = result->lnkcnt; |
node->type = result->type; |
link_initialize(&node->nh_link); |
rwlock_initialize(&node->contents_rwlock); |
hash_table_insert(&nodes, key, &node->nh_link); |
} else { |
node = hash_table_get_instance(tmp, vfs_node_t, nh_link); |
if (node->type == VFS_NODE_UNKNOWN && |
result->type != VFS_NODE_UNKNOWN) { |
/* Upgrade the node type. */ |
node->type = result->type; |
} |
} |
assert(node->size == result->size); |
assert(node->lnkcnt == result->lnkcnt); |
assert(node->type == result->type || result->type == VFS_NODE_UNKNOWN); |
_vfs_node_addref(node); |
futex_up(&nodes_futex); |
/branches/dd/uspace/srv/vfs/vfs.c |
---|
28,11 → 28,11 |
/** @addtogroup fs |
* @{ |
*/ |
*/ |
/** |
* @file vfs.c |
* @brief VFS service for HelenOS. |
* @file vfs.c |
* @brief VFS service for HelenOS. |
*/ |
#include <ipc/ipc.h> |
47,18 → 47,20 |
#include <atomic.h> |
#include "vfs.h" |
#define NAME "vfs" |
#define dprintf(...) printf(__VA_ARGS__) |
static void vfs_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
bool keep_on_going = true; |
bool keep_on_going = 1; |
printf("Connection opened from %p\n", icall->in_phone_hash); |
/* |
* The connection was opened via the IPC_CONNECT_ME_TO call. |
* This call needs to be answered. |
*/ |
ipc_answer_0(iid, EOK); |
/* |
* Here we enter the main connection fibril loop. |
* The logic behind this loop and the protocol is that we'd like to keep |
70,38 → 72,20 |
* connection later. |
*/ |
while (keep_on_going) { |
ipc_callid_t callid; |
ipc_call_t call; |
ipc_callid_t callid = async_get_call(&call); |
callid = async_get_call(&call); |
printf("Received call, method=%d\n", IPC_GET_METHOD(call)); |
fs_handle_t fs_handle; |
int phone; |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
keep_on_going = false; |
break; |
case IPC_M_CONNECT_ME_TO: |
/* |
* Connect the client file system to another one. |
*/ |
/* FIXME: |
* Prevent ordinary clients from connecting to file |
* system servers directly. This should be solved by |
* applying some security mechanisms. |
*/ |
fs_handle = IPC_GET_ARG1(call); |
phone = vfs_grab_phone(fs_handle); |
(void) ipc_forward_fast(callid, phone, 0, 0, 0, |
IPC_FF_NONE); |
vfs_release_phone(phone); |
break; |
case VFS_REGISTER: |
vfs_register(callid, &call); |
/* |
* Keep the connection open so that a file system can |
* later ask us to connect it to another file system. |
* This is necessary to support non-root mounts. |
*/ |
keep_on_going = false; |
break; |
case VFS_MOUNT: |
vfs_mount(callid, &call); |
138,27 → 122,30 |
break; |
} |
} |
/* TODO: cleanup after the client */ |
/* TODO: cleanup after the client */ |
} |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS VFS server\n"); |
ipcarg_t phonead; |
printf("VFS: HelenOS VFS server\n"); |
/* |
* Initialize the list of registered file systems. |
*/ |
list_initialize(&fs_head); |
/* |
* Initialize VFS node hash table. |
*/ |
if (!vfs_nodes_init()) { |
printf(NAME ": Failed to initialize VFS node hash table\n"); |
printf("Failed to initialize the VFS node hash table.\n"); |
return ENOMEM; |
} |
/* |
* Allocate and initialize the Path Lookup Buffer. |
*/ |
165,13 → 152,12 |
list_initialize(&plb_head); |
plb = as_get_mappable_page(PLB_SIZE); |
if (!plb) { |
printf(NAME ": Cannot allocate a mappable piece of address space\n"); |
printf("Cannot allocate a mappable piece of address space\n"); |
return ENOMEM; |
} |
if (as_area_create(plb, PLB_SIZE, AS_AREA_READ | AS_AREA_WRITE | |
AS_AREA_CACHEABLE) != plb) { |
printf(NAME ": Cannot create address space area\n"); |
printf("Cannot create address space area.\n"); |
return ENOMEM; |
} |
memset(plb, 0, PLB_SIZE); |
180,17 → 166,15 |
* Set a connectio handling function/fibril. |
*/ |
async_set_client_connection(vfs_connection); |
/* |
* Register at the naming service. |
*/ |
ipcarg_t phonead; |
ipc_connect_to_me(PHONE_NS, SERVICE_VFS, 0, 0, &phonead); |
/* |
* Start accepting connections. |
*/ |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
return 0; |
} |
197,4 → 181,4 |
/** |
* @} |
*/ |
*/ |
/branches/dd/uspace/srv/vfs/vfs_file.c |
---|
97,17 → 97,13 |
/** Release file descriptor. |
* |
* @param fd File descriptor being released. |
* |
* @return EOK on success or EBADF if fd is an invalid file |
* descriptor. |
*/ |
int vfs_fd_free(int fd) |
void vfs_fd_free(int fd) |
{ |
if ((fd >= MAX_OPEN_FILES) || (files[fd] == NULL)) |
return EBADF; |
assert(fd < MAX_OPEN_FILES); |
assert(files[fd] != NULL); |
vfs_file_delref(files[fd]); |
files[fd] = NULL; |
return EOK; |
} |
/** Increment reference count of VFS file structure. |
/branches/dd/uspace/srv/vfs/Makefile |
---|
32,7 → 32,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
53,24 → 52,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/console/console.c |
---|
35,32 → 35,27 |
#include <libc.h> |
#include <fb.h> |
#include <ipc/ipc.h> |
#include <kbd.h> |
#include <kbd/keycode.h> |
#include <keys.h> |
#include <ipc/fb.h> |
#include <ipc/services.h> |
#include <errno.h> |
#include <key_buffer.h> |
#include <ipc/console.h> |
#include <console.h> |
#include <unistd.h> |
#include <async.h> |
#include <libadt/fifo.h> |
#include <screenbuffer.h> |
#include <sys/mman.h> |
#include <stdio.h> |
#include <sysinfo.h> |
#include "console.h" |
#include "gcons.h" |
#define MAX_KEYREQUESTS_BUFFERED 32 |
#define NAME "console" |
#define NAME "CONSOLE" |
/** Index of currently used virtual console. |
*/ |
int active_console = 0; |
int prev_console = 0; |
/** Information about framebuffer |
*/ |
90,7 → 85,10 |
* faster virtual console |
* switching */ |
static int kernel_pixmap = -1; /**< Number of fb pixmap, where kernel |
* console is stored */ |
/** Find unused virtual console. |
* |
*/ |
110,54 → 108,27 |
async_msg_0(fb_info.phone, FB_CLEAR); |
} |
static void curs_visibility(bool visible) |
static void curs_visibility(int v) |
{ |
async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, visible); |
async_msg_1(fb_info.phone, FB_CURSOR_VISIBILITY, v); |
} |
static void curs_hide_sync(void) |
{ |
ipc_call_sync_1_0(fb_info.phone, FB_CURSOR_VISIBILITY, false); |
} |
static void curs_goto(int row, int col) |
{ |
async_msg_2(fb_info.phone, FB_CURSOR_GOTO, row, col); |
} |
static void set_style(int style) |
static void set_style(style_t *style) |
{ |
async_msg_1(fb_info.phone, FB_SET_STYLE, style); |
async_msg_2(fb_info.phone, FB_SET_STYLE, style->fg_color, |
style->bg_color); |
} |
static void set_color(int fgcolor, int bgcolor, int flags) |
static void set_style_col(int fgcolor, int bgcolor) |
{ |
async_msg_3(fb_info.phone, FB_SET_COLOR, fgcolor, bgcolor, flags); |
async_msg_2(fb_info.phone, FB_SET_STYLE, fgcolor, bgcolor); |
} |
static void set_rgb_color(int fgcolor, int bgcolor) |
{ |
async_msg_2(fb_info.phone, FB_SET_RGB_COLOR, fgcolor, bgcolor); |
} |
static void set_attrs(attrs_t *attrs) |
{ |
switch (attrs->t) { |
case at_style: |
set_style(attrs->a.s.style); |
break; |
case at_idx: |
set_color(attrs->a.i.fg_color, attrs->a.i.bg_color, |
attrs->a.i.flags); |
break; |
case at_rgb: |
set_rgb_color(attrs->a.r.fg_color, attrs->a.r.bg_color); |
break; |
} |
} |
static void prtchr(char c, int row, int col) |
{ |
async_msg_3(fb_info.phone, FB_PUTCHAR, c, row, col); |
215,81 → 186,114 |
} |
/** Save current screen to pixmap, draw old pixmap |
* |
* @param oldpixmap Old pixmap |
* @return ID of pixmap of current screen |
*/ |
static int switch_screens(int oldpixmap) |
{ |
int newpmap; |
/* Save screen */ |
newpmap = async_req_0_0(fb_info.phone, FB_VP2PIXMAP); |
if (newpmap < 0) |
return -1; |
if (oldpixmap != -1) { |
/* Show old screen */ |
async_msg_2(fb_info.phone, FB_VP_DRAW_PIXMAP, 0, oldpixmap); |
/* Drop old pixmap */ |
async_msg_1(fb_info.phone, FB_DROP_PIXMAP, oldpixmap); |
} |
return newpmap; |
} |
/** Switch to new console */ |
static void change_console(int newcons) |
{ |
connection_t *conn; |
static int console_pixmap = -1; |
int i, j, rc; |
keyfield_t *field; |
attrs_t *attrs; |
style_t *style; |
if (newcons == active_console) |
return; |
if (newcons == KERNEL_CONSOLE) { |
if (active_console == KERNEL_CONSOLE) |
return; |
active_console = KERNEL_CONSOLE; |
curs_visibility(0); |
async_serialize_start(); |
curs_hide_sync(); |
gcons_in_kernel(); |
if (kernel_pixmap == -1) { |
/* store/restore unsupported */ |
set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
clrscr(); |
} else { |
gcons_in_kernel(); |
console_pixmap = switch_screens(kernel_pixmap); |
kernel_pixmap = -1; |
} |
async_serialize_end(); |
if (__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE)) { |
prev_console = active_console; |
active_console = KERNEL_CONSOLE; |
} else |
newcons = active_console; |
__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); |
return; |
} |
async_serialize_start(); |
if (console_pixmap != -1) { |
kernel_pixmap = switch_screens(console_pixmap); |
console_pixmap = -1; |
} |
active_console = newcons; |
gcons_change_console(newcons); |
conn = &connections[active_console]; |
set_style(&conn->screenbuffer.style); |
curs_visibility(0); |
if (interbuffer) { |
for (i = 0; i < conn->screenbuffer.size_x; i++) |
for (j = 0; j < conn->screenbuffer.size_y; j++) { |
unsigned int size_x; |
size_x = conn->screenbuffer.size_x; |
interbuffer[i + j * size_x] = |
*get_field_at(&conn->screenbuffer, i, j); |
} |
/* This call can preempt, but we are already at the end */ |
rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA); |
} |
if (newcons != KERNEL_CONSOLE) { |
async_serialize_start(); |
if (active_console == KERNEL_CONSOLE) |
gcons_redraw_console(); |
active_console = newcons; |
gcons_change_console(newcons); |
conn = &connections[active_console]; |
set_attrs(&conn->screenbuffer.attrs); |
curs_visibility(false); |
if (interbuffer) { |
for (i = 0; i < conn->screenbuffer.size_x; i++) |
for (j = 0; j < conn->screenbuffer.size_y; j++) { |
unsigned int size_x; |
size_x = conn->screenbuffer.size_x; |
interbuffer[i + j * size_x] = |
*get_field_at(&conn->screenbuffer, i, j); |
} |
/* This call can preempt, but we are already at the end */ |
rc = async_req_0_0(fb_info.phone, FB_DRAW_TEXT_DATA); |
} |
if ((!interbuffer) || (rc != 0)) { |
set_attrs(&conn->screenbuffer.attrs); |
clrscr(); |
attrs = &conn->screenbuffer.attrs; |
for (j = 0; j < conn->screenbuffer.size_y; j++) |
for (i = 0; i < conn->screenbuffer.size_x; i++) { |
field = get_field_at(&conn->screenbuffer, i, j); |
if (!attrs_same(*attrs, field->attrs)) |
set_attrs(&field->attrs); |
attrs = &field->attrs; |
if ((field->character == ' ') && |
(attrs_same(field->attrs, |
conn->screenbuffer.attrs))) |
continue; |
if ((!interbuffer) || (rc != 0)) { |
set_style(&conn->screenbuffer.style); |
clrscr(); |
style = &conn->screenbuffer.style; |
prtchr(field->character, j, i); |
} |
} |
curs_goto(conn->screenbuffer.position_y, |
conn->screenbuffer.position_x); |
curs_visibility(conn->screenbuffer.is_cursor_visible); |
async_serialize_end(); |
for (j = 0; j < conn->screenbuffer.size_y; j++) |
for (i = 0; i < conn->screenbuffer.size_x; i++) { |
field = get_field_at(&conn->screenbuffer, i, j); |
if (!style_same(*style, field->style)) |
set_style(&field->style); |
style = &field->style; |
if ((field->character == ' ') && |
(style_same(field->style, |
conn->screenbuffer.style))) |
continue; |
prtchr(field->character, j, i); |
} |
} |
curs_goto(conn->screenbuffer.position_y, |
conn->screenbuffer.position_x); |
curs_visibility(conn->screenbuffer.is_cursor_visible); |
async_serialize_end(); |
} |
/** Handler for keyboard */ |
298,7 → 302,7 |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
kbd_event_t ev; |
int c; |
connection_t *conn; |
int newcon; |
320,24 → 324,23 |
IPC_GET_ARG2(call)); |
retval = 0; |
break; |
case KBD_EVENT: |
/* Got event from keyboard driver. */ |
case KBD_PUSHCHAR: |
/* got key from keyboard driver */ |
retval = 0; |
ev.type = IPC_GET_ARG1(call); |
ev.key = IPC_GET_ARG2(call); |
ev.mods = IPC_GET_ARG3(call); |
ev.c = IPC_GET_ARG4(call); |
c = IPC_GET_ARG1(call); |
/* switch to another virtual console */ |
conn = &connections[active_console]; |
if ((ev.key >= KC_F1) && (ev.key < KC_F1 + |
CONSOLE_COUNT)) { |
if (ev.key == KC_F12) |
/* |
* if ((c >= KBD_KEY_F1) && (c < KBD_KEY_F1 + |
* CONSOLE_COUNT)) { |
*/ |
if ((c >= 0x101) && (c < 0x101 + CONSOLE_COUNT)) { |
if (c == 0x112) |
change_console(KERNEL_CONSOLE); |
else |
change_console(ev.key - KC_F1); |
change_console(c - 0x101); |
break; |
} |
344,14 → 347,14 |
/* if client is awaiting key, send it */ |
if (conn->keyrequest_counter > 0) { |
conn->keyrequest_counter--; |
ipc_answer_4(fifo_pop(conn->keyrequests), EOK, |
ev.type, ev.key, ev.mods, ev.c); |
ipc_answer_1(fifo_pop(conn->keyrequests), EOK, |
c); |
break; |
} |
keybuffer_push(&conn->keybuffer, &ev); |
keybuffer_push(&conn->keybuffer, c); |
retval = 0; |
break; |
default: |
retval = ENOENT; |
366,9 → 369,9 |
ipc_callid_t callid; |
ipc_call_t call; |
int consnum; |
ipcarg_t arg1, arg2, arg3, arg4; |
ipcarg_t arg1, arg2; |
connection_t *conn; |
if ((consnum = find_free_connection()) == -1) { |
ipc_answer_0(iid, ELIMIT); |
return; |
383,23 → 386,20 |
/* Accept the connection */ |
ipc_answer_0(iid, EOK); |
while (1) { |
async_serialize_end(); |
callid = async_get_call(&call); |
async_serialize_start(); |
arg1 = 0; |
arg2 = 0; |
arg3 = 0; |
arg4 = 0; |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
gcons_notify_disconnect(consnum); |
/* Answer all pending requests */ |
while (conn->keyrequest_counter > 0) { |
while (conn->keyrequest_counter > 0) { |
conn->keyrequest_counter--; |
ipc_answer_0(fifo_pop(conn->keyrequests), |
ENOENT); |
437,26 → 437,11 |
break; |
case CONSOLE_SET_STYLE: |
arg1 = IPC_GET_ARG1(call); |
screenbuffer_set_style(&conn->screenbuffer, arg1); |
if (consnum == active_console) |
set_style(arg1); |
break; |
case CONSOLE_SET_COLOR: |
arg1 = IPC_GET_ARG1(call); |
arg2 = IPC_GET_ARG2(call); |
arg3 = IPC_GET_ARG3(call); |
screenbuffer_set_color(&conn->screenbuffer, arg1, |
arg2, arg3); |
if (consnum == active_console) |
set_color(arg1, arg2, arg3); |
break; |
case CONSOLE_SET_RGB_COLOR: |
arg1 = IPC_GET_ARG1(call); |
arg2 = IPC_GET_ARG2(call); |
screenbuffer_set_rgb_color(&conn->screenbuffer, arg1, |
screenbuffer_set_style(&conn->screenbuffer, arg1, |
arg2); |
if (consnum == active_console) |
set_rgb_color(arg1, arg2); |
set_style_col(arg1, arg2); |
break; |
case CONSOLE_CURSOR_VISIBILITY: |
arg1 = IPC_GET_ARG1(call); |
464,7 → 449,7 |
if (consnum == active_console) |
curs_visibility(arg1); |
break; |
case CONSOLE_GETKEY: |
case CONSOLE_GETCHAR: |
if (keybuffer_empty(&conn->keybuffer)) { |
/* buffer is empty -> store request */ |
if (conn->keyrequest_counter < |
480,66 → 465,54 |
} |
continue; |
} |
kbd_event_t ev; |
keybuffer_pop(&conn->keybuffer, &ev); |
arg1 = ev.type; |
arg2 = ev.key; |
arg3 = ev.mods; |
arg4 = ev.c; |
keybuffer_pop(&conn->keybuffer, (int *) &arg1); |
break; |
} |
ipc_answer_4(callid, EOK, arg1, arg2, arg3, arg4); |
ipc_answer_2(callid, EOK, arg1, arg2); |
} |
} |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
change_console(prev_console); |
} |
int main(int argc, char *argv[]) |
{ |
printf(NAME ": HelenOS Console service\n"); |
ipcarg_t phonehash; |
int kbd_phone; |
size_t ib_size; |
int i; |
async_set_client_connection(client_connection); |
/* Connect to keyboard driver */ |
kbd_phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
if (kbd_phone < 0) { |
printf(NAME ": Failed to connect to keyboard service\n"); |
return -1; |
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
while (kbd_phone < 0) { |
usleep(10000); |
kbd_phone = ipc_connect_me_to(PHONE_NS, SERVICE_KEYBOARD, 0, 0); |
} |
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) { |
printf(NAME ": Failed to create callback from keyboard service\n"); |
if (ipc_connect_to_me(kbd_phone, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) |
return -1; |
} |
async_new_connection(phonehash, 0, NULL, keyboard_events); |
/* Connect to framebuffer driver */ |
fb_info.phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_VIDEO, 0, 0); |
if (fb_info.phone < 0) { |
printf(NAME ": Failed to connect to video service\n"); |
return -1; |
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
while (fb_info.phone < 0) { |
usleep(10000); |
fb_info.phone = ipc_connect_me_to(PHONE_NS, SERVICE_VIDEO, 0, 0); |
} |
/* Disable kernel output to the console */ |
__SYSCALL0(SYS_DEBUG_DISABLE_CONSOLE); |
/* Save old kernel screen */ |
kernel_pixmap = switch_screens(-1); |
/* Initialize gcons */ |
gcons_init(fb_info.phone); |
/* Synchronize, the gcons can have something in queue */ |
async_req_0_0(fb_info.phone, FB_FLUSH); |
/* Enable double buffering */ |
async_msg_2(fb_info.phone, FB_VIEWPORT_DB, (sysarg_t) -1, 1); |
async_req_0_2(fb_info.phone, FB_GET_CSIZE, &fb_info.rows, |
&fb_info.cols); |
set_rgb_color(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
set_style_col(DEFAULT_FOREGROUND, DEFAULT_BACKGROUND); |
clrscr(); |
/* Init virtual consoles */ |
559,48 → 532,32 |
} |
} |
connections[KERNEL_CONSOLE].used = 1; |
/* Set up shared memory buffer. */ |
ib_size = sizeof(keyfield_t) * fb_info.cols * fb_info.rows; |
interbuffer = as_get_mappable_page(ib_size); |
if (as_area_create(interbuffer, ib_size, AS_AREA_READ | |
AS_AREA_WRITE | AS_AREA_CACHEABLE) != interbuffer) { |
interbuffer = NULL; |
} |
if (interbuffer) { |
interbuffer = mmap(NULL, |
sizeof(keyfield_t) * fb_info.cols * fb_info.rows, |
PROTO_READ | PROTO_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
if (!interbuffer) { |
if (ipc_share_out_start(fb_info.phone, interbuffer, |
AS_AREA_READ) != EOK) { |
as_area_destroy(interbuffer); |
munmap(interbuffer, |
sizeof(keyfield_t) * fb_info.cols * fb_info.rows); |
interbuffer = NULL; |
} |
} |
curs_goto(0, 0); |
curs_visibility( |
connections[active_console].screenbuffer.is_cursor_visible); |
/* Register at NS */ |
if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) |
if (ipc_connect_to_me(PHONE_NS, SERVICE_CONSOLE, 0, 0, &phonehash) != 0) { |
return -1; |
/* Receive kernel notifications */ |
if (sysinfo_value("kconsole.present")) { |
int devno = sysinfo_value("kconsole.devno"); |
int inr = sysinfo_value("kconsole.inr"); |
if (ipc_register_irq(inr, devno, 0, NULL) != EOK) |
printf(NAME ": Error registering kconsole notifications\n"); |
async_set_interrupt_received(interrupt_received); |
} |
// FIXME: avoid connectiong to itself, keep using klog |
// printf(NAME ": Accepting connections\n"); |
async_manager(); |
return 0; |
return 0; |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/console/gcons.c |
---|
81,7 → 81,7 |
static void vp_switch(int vp) |
{ |
async_msg_1(fbphone, FB_VIEWPORT_SWITCH, vp); |
async_msg_1(fbphone,FB_VIEWPORT_SWITCH, vp); |
} |
/** Create view port */ |
97,15 → 97,15 |
async_msg_0(fbphone, FB_CLEAR); |
} |
static void set_rgb_color(int fgcolor, int bgcolor) |
static void set_style(int fgcolor, int bgcolor) |
{ |
async_msg_2(fbphone, FB_SET_RGB_COLOR, fgcolor, bgcolor); |
async_msg_2(fbphone, FB_SET_STYLE, fgcolor, bgcolor); |
} |
/** Transparent putchar */ |
static void tran_putch(char c, int row, int col) |
{ |
async_msg_3(fbphone, FB_PUTCHAR, c, row, col); |
async_msg_3(fbphone, FB_TRANS_PUTCHAR, c, row, col); |
} |
/** Redraw the button showing state of a given console */ |
189,10 → 189,10 |
console_state[consnum] = CONS_DISCONNECTED_SEL; |
else |
console_state[consnum] = CONS_DISCONNECTED; |
if (active_console == KERNEL_CONSOLE) |
return; |
redraw_state(consnum); |
vp_switch(console_vp); |
} |
217,10 → 217,16 |
/** Change to kernel console */ |
void gcons_in_kernel(void) |
{ |
if (console_state[active_console] == CONS_DISCONNECTED_SEL) |
console_state[active_console] = CONS_DISCONNECTED; |
else |
console_state[active_console] = CONS_IDLE; |
redraw_state(active_console); |
if (animation != -1) |
async_msg_1(fbphone, FB_ANIM_STOP, animation); |
active_console = KERNEL_CONSOLE; |
active_console = KERNEL_CONSOLE; /* Set to kernel console */ |
vp_switch(0); |
} |
244,8 → 250,8 |
*/ |
void gcons_mouse_move(int dx, int dy) |
{ |
mouse_x = limit(mouse_x + dx, 0, xres); |
mouse_y = limit(mouse_y + dy, 0, yres); |
mouse_x = limit(mouse_x+dx, 0, xres); |
mouse_y = limit(mouse_y+dy, 0, yres); |
async_msg_2(fbphone, FB_POINTER_MOVE, mouse_x, mouse_y); |
} |
252,7 → 258,7 |
static int gcons_find_conbut(int x, int y) |
{ |
int status_start = STATUS_START + (xres - 800) / 2; |
int status_start = STATUS_START + (xres - 800) / 2;; |
if (y < STATUS_TOP || y >= STATUS_TOP + STATUS_HEIGHT) |
return -1; |
262,10 → 268,10 |
if (x >= status_start + (STATUS_WIDTH + STATUS_SPACE) * CONSOLE_COUNT) |
return -1; |
if (((x - status_start) % (STATUS_WIDTH + STATUS_SPACE)) < STATUS_SPACE) |
if (((x - status_start) % (STATUS_WIDTH+STATUS_SPACE)) < STATUS_SPACE) |
return -1; |
return (x - status_start) / (STATUS_WIDTH + STATUS_SPACE); |
return (x - status_start) / (STATUS_WIDTH+STATUS_SPACE); |
} |
/** Handle mouse click |
336,23 → 342,22 |
extern int _binary_helenos_ppm_size; |
extern char _binary_nameic_ppm_start[0]; |
extern int _binary_nameic_ppm_size; |
/** Redraws console graphics */ |
void gcons_redraw_console(void) |
/** Redraws console graphics */ |
static void gcons_redraw_console(void) |
{ |
int i; |
if (!use_gcons) |
return; |
vp_switch(0); |
set_rgb_color(MAIN_COLOR, MAIN_COLOR); |
set_style(MAIN_COLOR, MAIN_COLOR); |
clear(); |
draw_pixmap(_binary_helenos_ppm_start, |
(size_t) &_binary_helenos_ppm_size, xres - 66, 2); |
draw_pixmap(_binary_nameic_ppm_start, |
(size_t) &_binary_nameic_ppm_size, 5, 17); |
for (i = 0; i < CONSOLE_COUNT; i++) |
redraw_state(i); |
vp_switch(console_vp); |
454,16 → 459,16 |
int rc; |
int i; |
int status_start = STATUS_START; |
fbphone = phone; |
rc = async_req_0_2(phone, FB_GET_RESOLUTION, &xres, &yres); |
if (rc) |
return; |
if ((xres < 800) || (yres < 600)) |
if (xres < 800 || yres < 600) |
return; |
/* create console viewport */ |
/* Align width & height to character size */ |
console_vp = vp_create(CONSOLE_MARGIN, CONSOLE_TOP, |
481,7 → 486,7 |
if (cstatus_vp[i] < 0) |
return; |
vp_switch(cstatus_vp[i]); |
set_rgb_color(0x202020, 0xffffff); |
set_style(0x202020, 0xffffff); |
} |
/* Initialize icons */ |
501,12 → 506,13 |
ic_pixmaps[CONS_DISCONNECTED_SEL] = ic_pixmaps[CONS_SELECTED]; |
make_anim(); |
use_gcons = 1; |
console_state[0] = CONS_DISCONNECTED_SEL; |
console_state[KERNEL_CONSOLE] = CONS_KERNEL; |
gcons_redraw_console(); |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/console/Makefile |
---|
31,9 → 31,8 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I. -I../kbd/include -I../fb |
LIBS = $(LIBC_PREFIX)/libc.a |
58,28 → 57,24 |
$(addsuffix .o,$(basename $(IMAGES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
OBJECTS := $(GENERIC_OBJECTS) $(ARCH_OBJECTS) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld -e __entry_driver $(GENERIC_OBJECTS) $(ARCH_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/console/console.h |
---|
39,6 → 39,15 |
#define CONSOLE_COUNT 12 |
#define CONSOLE_GETCHAR 1026 |
#define CONSOLE_PUTCHAR 1027 |
#define CONSOLE_CLEAR 1028 |
#define CONSOLE_GOTO 1029 |
#define CONSOLE_GETSIZE 1030 |
#define CONSOLE_FLUSH 1031 |
#define CONSOLE_SET_STYLE 1032 |
#define CONSOLE_CURSOR_VISIBILITY 1033 |
#endif |
/** @} |
/branches/dd/uspace/srv/console/screenbuffer.c |
---|
33,7 → 33,6 |
*/ |
#include <screenbuffer.h> |
#include <console/style.h> |
#include <malloc.h> |
#include <unistd.h> |
50,7 → 49,7 |
field = get_field_at(scr, scr->position_x, scr->position_y); |
field->character = c; |
field->attrs = scr->attrs; |
field->style = scr->style; |
} |
/** Initilize screenbuffer. Allocate space for screen content in accordance to given size. |
68,8 → 67,8 |
scr->size_x = size_x; |
scr->size_y = size_y; |
scr->attrs.t = at_style; |
scr->attrs.a.s.style = STYLE_NORMAL; |
scr->style.fg_color = DEFAULT_FOREGROUND; |
scr->style.bg_color = DEFAULT_BACKGROUND; |
scr->is_cursor_visible = 1; |
screenbuffer_clear(scr); |
86,7 → 85,7 |
for (i = 0; i < (scr->size_x * scr->size_y); i++) { |
scr->buffer[i].character = ' '; |
scr->buffer[i].attrs = scr->attrs; |
scr->buffer[i].style = scr->style; |
} |
scr->top_line = 0; |
104,7 → 103,7 |
for (i = 0; i < scr->size_x; i++) { |
scr->buffer[i + line * scr->size_x].character = ' '; |
scr->buffer[i + line * scr->size_x].attrs = scr->attrs; |
scr->buffer[i + line * scr->size_x].style = scr->style; |
} |
} |
137,37 → 136,12 |
* @param fg_color |
* @param bg_color |
*/ |
void screenbuffer_set_style(screenbuffer_t *scr, int style) |
void screenbuffer_set_style(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color) |
{ |
scr->attrs.t = at_style; |
scr->attrs.a.s.style = style; |
scr->style.fg_color = fg_color; |
scr->style.bg_color = bg_color; |
} |
/** Set new color. |
* @param scr |
* @param fg_color |
* @param bg_color |
*/ |
void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color, unsigned int flags) |
{ |
scr->attrs.t = at_idx; |
scr->attrs.a.i.fg_color = fg_color; |
scr->attrs.a.i.bg_color = bg_color; |
scr->attrs.a.i.flags = flags; |
} |
/** Set new RGB color. |
* @param scr |
* @param fg_color |
* @param bg_color |
*/ |
void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color) |
{ |
scr->attrs.t = at_rgb; |
scr->attrs.a.r.fg_color = fg_color; |
scr->attrs.a.r.bg_color = bg_color; |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/console/gcons.h |
---|
36,7 → 36,6 |
#define _GCONS_H_ |
void gcons_init(int phone); |
void gcons_redraw_console(void); |
void gcons_change_console(int consnum); |
void gcons_notify_char(int consnum); |
void gcons_in_kernel(void); |
/branches/dd/uspace/srv/console/screenbuffer.h |
---|
35,52 → 35,28 |
#ifndef __SCREENBUFFER_H__ |
#define __SCREENBUFFER_H__ |
#include <stdint.h> |
#define DEFAULT_FOREGROUND 0x0 /**< default console foreground color */ |
#define DEFAULT_BACKGROUND 0xf0f0f0 /**< default console background color */ |
typedef struct { |
uint8_t style; |
} attr_style_t; |
unsigned int bg_color; /**< background color */ |
unsigned int fg_color; /**< foreground color */ |
} style_t; |
typedef struct { |
uint8_t fg_color; |
uint8_t bg_color; |
uint8_t flags; |
} attr_idx_t; |
typedef struct { |
uint32_t bg_color; /**< background color */ |
uint32_t fg_color; /**< foreground color */ |
} attr_rgb_t; |
typedef struct { |
enum { |
at_style, |
at_idx, |
at_rgb |
} t; |
union { |
attr_style_t s; |
attr_idx_t i; |
attr_rgb_t r; |
} a; |
} attrs_t; |
/** One field on screen. It contain one character and its attributes. */ |
typedef struct { |
char character; /**< Character itself */ |
attrs_t attrs; /**< Character`s attributes */ |
style_t style; /**< Character`s attributes */ |
} keyfield_t; |
/** Structure for buffering state of one virtual console. |
*/ |
typedef struct { |
keyfield_t *buffer; /**< Screen content - characters and their attributes. Used as a circular buffer. */ |
keyfield_t *buffer; /**< Screen content - characters and its style. Used as cyclyc buffer. */ |
unsigned int size_x, size_y; /**< Number of columns and rows */ |
unsigned int position_x, position_y; /**< Coordinates of last printed character for determining cursor position */ |
attrs_t attrs; /**< Current attributes. */ |
style_t style; /**< Current style */ |
unsigned int top_line; /**< Points to buffer[][] line that will be printed at screen as the first line */ |
unsigned char is_cursor_visible; /**< Cursor state - default is visible */ |
} screenbuffer_t; |
96,23 → 72,14 |
return scr->buffer + x + ((y + scr->top_line) % scr->size_y) * scr->size_x; |
} |
/** Compares two sets of attributes. |
/** Compares two styles. |
* @param s1 first style |
* @param s2 second style |
* @return nonzero on equality |
*/ |
static inline int attrs_same(attrs_t a1, attrs_t a2) |
static inline int style_same(style_t s1, style_t s2) |
{ |
if (a1.t != a2.t) return 0; |
switch (a1.t) { |
case at_style: return a1.a.s.style == a2.a.s.style; |
case at_idx: return a1.a.i.fg_color == a2.a.i.fg_color && |
a1.a.i.bg_color == a2.a.i.bg_color && |
a1.a.i.flags == a2.a.i.flags; |
case at_rgb: return a1.a.r.fg_color == a2.a.r.fg_color && |
a1.a.r.bg_color == a2.a.r.bg_color; |
} |
return s1.fg_color == s2.fg_color && s1.bg_color == s2.bg_color; |
} |
123,11 → 90,7 |
void screenbuffer_clear_line(screenbuffer_t *scr, unsigned int line); |
void screenbuffer_copy_buffer(screenbuffer_t *scr, keyfield_t *dest); |
void screenbuffer_goto(screenbuffer_t *scr, unsigned int x, unsigned int y); |
void screenbuffer_set_style(screenbuffer_t *scr, int style); |
void screenbuffer_set_color(screenbuffer_t *scr, unsigned int fg_color, |
unsigned int bg_color, unsigned int attr); |
void screenbuffer_set_rgb_color(screenbuffer_t *scr, unsigned int fg_color, |
unsigned int bg_color); |
void screenbuffer_set_style(screenbuffer_t *scr, unsigned int fg_color, unsigned int bg_color); |
#endif |
/branches/dd/uspace/srv/rd/rd.c |
---|
51,12 → 51,8 |
#include <align.h> |
#include <async.h> |
#include <futex.h> |
#include <stdio.h> |
#include <ipc/devmap.h> |
#include "rd.h" |
#define NAME "rd" |
/** Pointer to the ramdisk's image. */ |
static void *rd_addr; |
/** Size of the ramdisk. */ |
81,24 → 77,45 |
ipc_call_t call; |
int retval; |
void *fs_va = NULL; |
off_t offset; |
size_t block_size; |
size_t maxblock_size; |
ipcarg_t offset; |
/* |
* Answer the first IPC_M_CONNECT_ME_TO call. |
* We allocate VA for communication per connection. |
* This allows us to potentionally have more clients and work |
* concurrently. |
*/ |
ipc_answer_0(iid, EOK); |
fs_va = as_get_mappable_page(ALIGN_UP(BLOCK_SIZE, PAGE_SIZE)); |
if (!fs_va) { |
/* |
* Hang up the phone if we cannot proceed any further. |
* This is the answer to the call that opened the connection. |
*/ |
ipc_answer_0(iid, EHANGUP); |
return; |
} else { |
/* |
* Answer the first IPC_M_CONNECT_ME_TO call. |
* Return supported block size as ARG1. |
*/ |
ipc_answer_1(iid, EOK, BLOCK_SIZE); |
} |
/* |
* Now we wait for the client to send us its communication as_area. |
*/ |
int flags; |
if (ipc_share_out_receive(&callid, &maxblock_size, &flags)) { |
fs_va = as_get_mappable_page(maxblock_size); |
if (fs_va) { |
size_t size; |
if (ipc_share_out_receive(&callid, &size, NULL)) { |
if (size >= BLOCK_SIZE) { |
/* |
* The client sends an as_area that can absorb the whole |
* block. |
*/ |
(void) ipc_share_out_finalize(callid, fs_va); |
} else { |
/* |
* The client offered as_area too small. |
* Close the connection. |
*/ |
ipc_answer_0(callid, EHANGUP); |
return; |
} |
124,16 → 141,8 |
return; |
case RD_READ_BLOCK: |
offset = IPC_GET_ARG1(call); |
block_size = IPC_GET_ARG2(call); |
if (block_size > maxblock_size) { |
if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
/* |
* Maximum block size exceeded. |
*/ |
retval = ELIMIT; |
break; |
} |
if (offset * block_size > rd_size - block_size) { |
/* |
* Reading past the end of the device. |
*/ |
retval = ELIMIT; |
140,22 → 149,14 |
break; |
} |
futex_down(&rd_futex); |
memcpy(fs_va, rd_addr + offset * block_size, block_size); |
memcpy(fs_va, rd_addr + offset, BLOCK_SIZE); |
futex_up(&rd_futex); |
retval = EOK; |
break; |
case RD_WRITE_BLOCK: |
offset = IPC_GET_ARG1(call); |
block_size = IPC_GET_ARG2(call); |
if (block_size > maxblock_size) { |
if (offset * BLOCK_SIZE > rd_size - BLOCK_SIZE) { |
/* |
* Maximum block size exceeded. |
*/ |
retval = ELIMIT; |
break; |
} |
if (offset * block_size > rd_size - block_size) { |
/* |
* Writing past the end of the device. |
*/ |
retval = ELIMIT; |
162,7 → 163,7 |
break; |
} |
futex_up(&rd_futex); |
memcpy(rd_addr + offset * block_size, fs_va, block_size); |
memcpy(rd_addr + offset, fs_va, BLOCK_SIZE); |
futex_down(&rd_futex); |
retval = EOK; |
break; |
180,117 → 181,46 |
} |
} |
static int driver_register(char *name) |
{ |
ipcarg_t retval; |
aid_t req; |
ipc_call_t answer; |
int phone; |
ipcarg_t callback_phonehash; |
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); |
if (phone < 0) { |
printf(NAME ": Failed to connect to device mapper\n"); |
return -1; |
} |
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); |
retval = ipc_data_write_start(phone, (char *) name, strlen(name) + 1); |
if (retval != EOK) { |
async_wait_for(req, NULL); |
return -1; |
} |
async_set_client_connection(rd_connection); |
ipc_connect_to_me(phone, 0, 0, 0, &callback_phonehash); |
async_wait_for(req, &retval); |
return phone; |
} |
static int device_register(int driver_phone, char *name, int *handle) |
{ |
ipcarg_t retval; |
aid_t req; |
ipc_call_t answer; |
req = async_send_2(driver_phone, DEVMAP_DEVICE_REGISTER, 0, 0, &answer); |
retval = ipc_data_write_start(driver_phone, (char *) name, strlen(name) + 1); |
if (retval != EOK) { |
async_wait_for(req, NULL); |
return retval; |
} |
async_wait_for(req, &retval); |
if (handle != NULL) |
*handle = -1; |
if (EOK == retval) { |
if (NULL != handle) |
*handle = (int) IPC_GET_ARG1(answer); |
} |
return retval; |
} |
/** Prepare the ramdisk image for operation. */ |
static bool rd_init(void) |
{ |
int retval, flags; |
rd_size = sysinfo_value("rd.size"); |
void *rd_ph_addr = (void *) sysinfo_value("rd.address.physical"); |
if (rd_size == 0) { |
printf(NAME ": No RAM disk found\n"); |
if (rd_size == 0) |
return false; |
} |
rd_addr = as_get_mappable_page(rd_size); |
int flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE; |
int retval = physmem_map(rd_ph_addr, rd_addr, |
flags = AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE; |
retval = physmem_map(rd_ph_addr, rd_addr, |
ALIGN_UP(rd_size, PAGE_SIZE) >> PAGE_WIDTH, flags); |
if (retval < 0) { |
printf(NAME ": Error mapping RAM disk\n"); |
if (retval < 0) |
return false; |
} |
printf(NAME ": Found RAM disk at %p, %d bytes\n", rd_ph_addr, rd_size); |
int driver_phone = driver_register(NAME); |
if (driver_phone < 0) { |
printf(NAME ": Unable to register driver\n"); |
return false; |
} |
int dev_handle; |
if (EOK != device_register(driver_phone, "initrd", &dev_handle)) { |
ipc_hangup(driver_phone); |
printf(NAME ": Unable to register device\n"); |
return false; |
} |
return true; |
} |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS RAM disk server\n"); |
if (rd_init()) { |
ipcarg_t phonead; |
async_set_client_connection(rd_connection); |
/* Register service at nameserver */ |
if (ipc_connect_to_me(PHONE_NS, SERVICE_RD, 0, 0, &phonead) != 0) |
return -1; |
async_manager(); |
/* Never reached */ |
return 0; |
} |
if (!rd_init()) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
return -1; |
} |
/** |
/branches/dd/uspace/srv/rd/Makefile |
---|
29,10 → 29,8 |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
48,24 → 46,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld -e __entry_driver $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/rd/rd.h |
---|
43,6 → 43,8 |
#ifndef RD_RD_H_ |
#define RD_RD_H_ |
#define BLOCK_SIZE 1024 /**< Working block size */ |
#define RD_BASE 1024 |
#define RD_READ_BLOCK (RD_BASE + 1) /**< Method for reading block. */ |
#define RD_WRITE_BLOCK (RD_BASE + 2) /**< Method for writing block. */ |
/branches/dd/uspace/srv/devmap/devmap.c |
---|
28,9 → 28,9 |
/** |
* @defgroup devmap Device mapper. |
* @brief HelenOS device mapper. |
* @brief HelenOS device mapper. |
* @{ |
*/ |
*/ |
/** @file |
*/ |
44,26 → 44,18 |
#include <futex.h> |
#include <stdlib.h> |
#include <string.h> |
#include <ipc/devmap.h> |
#define NAME "devmap" |
#include "devmap.h" |
/** Pending lookup structure. */ |
typedef struct { |
link_t link; |
char *name; /**< Device name */ |
ipc_callid_t callid; /**< Call ID waiting for the lookup */ |
} pending_req_t; |
LIST_INITIALIZE(devices_list); |
LIST_INITIALIZE(drivers_list); |
LIST_INITIALIZE(pending_req); |
/* Locking order: |
* drivers_list_futex |
* devices_list_futex |
* (devmap_driver_t *)->devices_futex |
* create_handle_futex |
/* order of locking: |
* drivers_list_futex |
* devices_list_futex |
* (devmap_driver_t *)->devices_futex |
* create_handle_futex |
**/ |
static atomic_t devices_list_futex = FUTEX_INITIALIZER; |
70,28 → 62,27 |
static atomic_t drivers_list_futex = FUTEX_INITIALIZER; |
static atomic_t create_handle_futex = FUTEX_INITIALIZER; |
static int devmap_create_handle(void) |
{ |
static int last_handle = 0; |
int handle; |
/* TODO: allow reusing old handles after their unregistration |
* and implement some version of LRU algorithm |
*/ |
and implement some version of LRU algorithm */ |
/* FIXME: overflow */ |
futex_down(&create_handle_futex); |
futex_down(&create_handle_futex); |
last_handle += 1; |
handle = last_handle; |
futex_up(&create_handle_futex); |
futex_up(&create_handle_futex); |
return handle; |
} |
/** Initialize device mapper. |
/** Initialize device mapper. |
* |
* |
*/ |
98,7 → 89,7 |
static int devmap_init() |
{ |
/* TODO: */ |
return EOK; |
} |
107,153 → 98,169 |
*/ |
static devmap_device_t *devmap_device_find_name(const char *name) |
{ |
link_t *item = devices_list.next; |
link_t *item; |
devmap_device_t *device = NULL; |
item = devices_list.next; |
while (item != &devices_list) { |
device = list_get_instance(item, devmap_device_t, devices); |
if (0 == strcmp(device->name, name)) |
if (0 == strcmp(device->name, name)) { |
break; |
} |
item = item->next; |
} |
if (item == &devices_list) |
if (item == &devices_list) { |
printf("DEVMAP: no device named %s.\n", name); |
return NULL; |
} |
device = list_get_instance(item, devmap_device_t, devices); |
return device; |
} |
/** Find device with given handle. |
* |
* @todo: use hash table |
* |
*/ |
static devmap_device_t *devmap_device_find_handle(int handle) |
{ |
futex_down(&devices_list_futex); |
link_t *item = (&devices_list)->next; |
link_t *item; |
devmap_device_t *device = NULL; |
futex_down(&devices_list_futex); |
item = (&devices_list)->next; |
while (item != &devices_list) { |
device = list_get_instance(item, devmap_device_t, devices); |
if (device->handle == handle) |
if (device->handle == handle) { |
break; |
} |
item = item->next; |
} |
if (item == &devices_list) { |
futex_up(&devices_list_futex); |
return NULL; |
} |
device = list_get_instance(item, devmap_device_t, devices); |
futex_up(&devices_list_futex); |
return device; |
} |
/** |
* |
* Unregister device and free it. It's assumed that driver's device list is |
* already locked. |
* |
*/ |
static int devmap_device_unregister_core(devmap_device_t *device) |
{ |
list_remove(&(device->devices)); |
list_remove(&(device->driver_devices)); |
free(device->name); |
free(device->name); |
free(device); |
return EOK; |
} |
/** |
* |
* Read info about new driver and add it into linked list of registered |
* drivers. |
* |
*/ |
static void devmap_driver_register(devmap_driver_t **odriver) |
{ |
size_t name_size; |
ipc_callid_t callid; |
ipc_call_t call; |
devmap_driver_t *driver; |
ipc_callid_t iid; |
ipc_call_t icall; |
*odriver = NULL; |
ipc_call_t icall; |
ipc_callid_t iid = async_get_call(&icall); |
iid = async_get_call(&icall); |
if (IPC_GET_METHOD(icall) != DEVMAP_DRIVER_REGISTER) { |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
devmap_driver_t *driver = (devmap_driver_t *) malloc(sizeof(devmap_driver_t)); |
if (driver == NULL) { |
} |
if (NULL == |
(driver = (devmap_driver_t *)malloc(sizeof(devmap_driver_t)))) { |
ipc_answer_0(iid, ENOMEM); |
return; |
} |
/* |
/* |
* Get driver name |
*/ |
ipc_callid_t callid; |
size_t name_size; |
if (!ipc_data_write_receive(&callid, &name_size)) { |
printf("Unexpected request.\n"); |
free(driver); |
ipc_answer_0(callid, EREFUSED); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
if (name_size > DEVMAP_NAME_MAXLEN) { |
printf("Too logn name: %u: maximum is %u.\n", name_size, |
DEVMAP_NAME_MAXLEN); |
free(driver); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
/* |
* Allocate buffer for device name. |
*/ |
driver->name = (char *) malloc(name_size + 1); |
if (driver->name == NULL) { |
if (NULL == (driver->name = (char *)malloc(name_size + 1))) { |
printf("Cannot allocate space for driver name.\n"); |
free(driver); |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
} |
/* |
* Send confirmation to sender and get data into buffer. |
*/ |
if (EOK != ipc_data_write_finalize(callid, driver->name, name_size)) { |
printf("Cannot read driver name.\n"); |
free(driver->name); |
free(driver); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
driver->name[name_size] = 0; |
printf("Read driver name: '%s'.\n", driver->name); |
/* Initialize futex for list of devices owned by this driver */ |
futex_initialize(&(driver->devices_futex), 1); |
/* |
/* |
* Initialize list of asociated devices |
*/ |
list_initialize(&(driver->devices)); |
/* |
/* |
* Create connection to the driver |
*/ |
ipc_call_t call; |
callid = async_get_call(&call); |
if (IPC_M_CONNECT_TO_ME != IPC_GET_METHOD(call)) { |
printf("DEVMAP: Unexpected method: %u.\n", |
IPC_GET_METHOD(call)); |
ipc_answer_0(callid, ENOTSUP); |
free(driver->name); |
261,92 → 268,78 |
ipc_answer_0(iid, ENOTSUP); |
return; |
} |
driver->phone = IPC_GET_ARG5(call); |
ipc_answer_0(callid, EOK); |
list_initialize(&(driver->drivers)); |
futex_down(&drivers_list_futex); |
futex_down(&drivers_list_futex); |
/* TODO: |
* check that no driver with name equal to driver->name is registered |
*/ |
/* |
/* |
* Insert new driver into list of registered drivers |
*/ |
list_append(&(driver->drivers), &drivers_list); |
futex_up(&drivers_list_futex); |
futex_up(&drivers_list_futex); |
ipc_answer_0(iid, EOK); |
printf("Driver registered.\n"); |
*odriver = driver; |
return; |
} |
/** |
* Unregister device driver, unregister all its devices and free driver |
/** Unregister device driver, unregister all its devices and free driver |
* structure. |
* |
*/ |
static int devmap_driver_unregister(devmap_driver_t *driver) |
{ |
if (driver == NULL) |
devmap_device_t *device; |
if (NULL == driver) { |
printf("Error: driver == NULL.\n"); |
return EEXISTS; |
futex_down(&drivers_list_futex); |
} |
printf("Unregister driver '%s'.\n", driver->name); |
futex_down(&drivers_list_futex); |
ipc_hangup(driver->phone); |
/* remove it from list of drivers */ |
list_remove(&(driver->drivers)); |
/* unregister all its devices */ |
futex_down(&devices_list_futex); |
futex_down(&devices_list_futex); |
futex_down(&(driver->devices_futex)); |
while (!list_empty(&(driver->devices))) { |
devmap_device_t *device = list_get_instance(driver->devices.next, |
device = list_get_instance(driver->devices.next, |
devmap_device_t, driver_devices); |
printf("Unregister device '%s'.\n", device->name); |
devmap_device_unregister_core(device); |
} |
futex_up(&(driver->devices_futex)); |
futex_up(&devices_list_futex); |
futex_up(&drivers_list_futex); |
futex_up(&devices_list_futex); |
futex_up(&drivers_list_futex); |
/* free name and driver */ |
if (NULL != driver->name) |
if (NULL != driver->name) { |
free(driver->name); |
} |
free(driver); |
return EOK; |
} |
printf("Driver unregistered.\n"); |
/** Process pending lookup requests */ |
static void process_pending_lookup() |
{ |
link_t *cur; |
loop: |
for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
const devmap_device_t *dev = devmap_device_find_name(pr->name); |
if (!dev) |
continue; |
ipc_answer_1(pr->callid, EOK, dev->handle); |
free(pr->name); |
list_remove(cur); |
free(pr); |
goto loop; |
} |
return EOK; |
} |
356,38 → 349,45 |
static void devmap_device_register(ipc_callid_t iid, ipc_call_t *icall, |
devmap_driver_t *driver) |
{ |
if (driver == NULL) { |
ipc_callid_t callid; |
size_t size; |
devmap_device_t *device; |
if (NULL == driver) { |
printf("Invalid driver registration.\n"); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
/* Create new device entry */ |
devmap_device_t *device = (devmap_device_t *) malloc(sizeof(devmap_device_t)); |
if (device == NULL) { |
if (NULL == |
(device = (devmap_device_t *)malloc(sizeof(devmap_device_t)))) { |
printf("Cannot allocate new device.\n"); |
ipc_answer_0(iid, ENOMEM); |
return; |
} |
/* Get device name */ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_write_receive(&callid, &size)) { |
free(device); |
printf("Cannot read device name.\n"); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
if (size > DEVMAP_NAME_MAXLEN) { |
printf("Too long device name: %u.\n", size); |
free(device); |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
/* +1 for terminating \0 */ |
device->name = (char *) malloc(size + 1); |
if (device->name == NULL) { |
/* +1 for terminating \0 */ |
device->name = (char *)malloc(size + 1); |
if (NULL == device->name) { |
printf("Cannot read device name.\n"); |
free(device); |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(iid, EREFUSED); |
396,15 → 396,15 |
ipc_data_write_finalize(callid, device->name, size); |
device->name[size] = 0; |
list_initialize(&(device->devices)); |
list_initialize(&(device->driver_devices)); |
futex_down(&devices_list_futex); |
futex_down(&devices_list_futex); |
/* Check that device with such name is not already registered */ |
if (NULL != devmap_device_find_name(device->name)) { |
printf(NAME ": Device '%s' already registered\n", device->name); |
printf("Device '%s' already registered.\n", device->name); |
futex_up(&devices_list_futex); |
free(device->name); |
free(device); |
411,26 → 411,27 |
ipc_answer_0(iid, EEXISTS); |
return; |
} |
/* Get unique device handle */ |
device->handle = devmap_create_handle(); |
device->handle = devmap_create_handle(); |
device->driver = driver; |
/* Insert device into list of all devices */ |
list_append(&device->devices, &devices_list); |
/* Insert device into list of devices that belog to one driver */ |
futex_down(&device->driver->devices_futex); |
list_append(&device->driver_devices, &device->driver->devices); |
futex_up(&device->driver->devices_futex); |
futex_up(&devices_list_futex); |
futex_up(&device->driver->devices_futex); |
futex_up(&devices_list_futex); |
printf("Device '%s' registered.\n", device->name); |
ipc_answer_1(iid, EOK, device->handle); |
process_pending_lookup(); |
return; |
} |
/** |
440,174 → 441,179 |
devmap_driver_t *driver) |
{ |
/* TODO */ |
return EOK; |
} |
/** Connect client to the device. |
* |
* Find device driver owning requested device and forward |
* the message to it. |
* |
*/ |
static void devmap_forward(ipc_callid_t callid, ipc_call_t *call) |
{ |
devmap_device_t *dev; |
int handle; |
/* |
* Get handle from request |
*/ |
int handle = IPC_GET_ARG2(*call); |
devmap_device_t *dev = devmap_device_find_handle(handle); |
handle = IPC_GET_ARG2(*call); |
dev = devmap_device_find_handle(handle); |
if (NULL == dev) { |
printf("DEVMAP: No registered device with handle %d.\n", |
handle); |
ipc_answer_0(callid, ENOENT); |
return; |
} |
} |
ipc_forward_fast(callid, dev->driver->phone, (ipcarg_t)(dev->handle), |
IPC_GET_ARG3(*call), 0, IPC_FF_NONE); |
return; |
} |
/** Find handle for device instance identified by name. |
* |
* In answer will be send EOK and device handle in arg1 or a error |
* code from errno.h. |
* |
* code from errno.h. |
*/ |
static void devmap_get_handle(ipc_callid_t iid, ipc_call_t *icall) |
{ |
/* |
char *name = NULL; |
size_t name_size; |
const devmap_device_t *dev; |
ipc_callid_t callid; |
ipcarg_t retval; |
/* |
* Wait for incoming message with device name (but do not |
* read the name itself until the buffer is allocated). |
*/ |
ipc_callid_t callid; |
size_t size; |
if (!ipc_data_write_receive(&callid, &size)) { |
if (!ipc_data_write_receive(&callid, &name_size)) { |
ipc_answer_0(callid, EREFUSED); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
if ((size < 1) || (size > DEVMAP_NAME_MAXLEN)) { |
if (name_size > DEVMAP_NAME_MAXLEN) { |
ipc_answer_0(callid, EINVAL); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
/* |
* Allocate buffer for device name. |
*/ |
char *name = (char *) malloc(size); |
if (name == NULL) { |
if (NULL == (name = (char *)malloc(name_size))) { |
ipc_answer_0(callid, ENOMEM); |
ipc_answer_0(iid, EREFUSED); |
return; |
} |
} |
/* |
* Send confirmation to sender and get data into buffer. |
*/ |
ipcarg_t retval = ipc_data_write_finalize(callid, name, size); |
if (retval != EOK) { |
if (EOK != (retval = ipc_data_write_finalize(callid, name, |
name_size))) { |
ipc_answer_0(iid, EREFUSED); |
free(name); |
return; |
} |
name[size] = '\0'; |
/* |
* Find device name in linked list of known devices. |
*/ |
const devmap_device_t *dev = devmap_device_find_name(name); |
dev = devmap_device_find_name(name); |
/* |
* Device was not found. |
*/ |
if (dev == NULL) { |
if (IPC_GET_ARG1(*icall) & IPC_FLAG_BLOCKING) { |
/* Blocking lookup, add to pending list */ |
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
if (!pr) { |
ipc_answer_0(iid, ENOMEM); |
free(name); |
return; |
} |
pr->name = name; |
pr->callid = iid; |
list_append(&pr->link, &pending_req); |
return; |
} |
if (NULL == dev) { |
printf("DEVMAP: device %s has not been registered.\n", name); |
ipc_answer_0(iid, ENOENT); |
free(name); |
return; |
} |
printf("DEVMAP: device %s has handler %d.\n", name, dev->handle); |
ipc_answer_1(iid, EOK, dev->handle); |
free(name); |
return; |
} |
/** Find name of device identified by id and send it to caller. |
/** Find name of device identified by id and send it to caller. |
* |
*/ |
static void devmap_get_name(ipc_callid_t iid, ipc_call_t *icall) |
{ |
const devmap_device_t *device = devmap_device_find_handle(IPC_GET_ARG1(*icall)); |
const devmap_device_t *device; |
size_t name_size; |
device = devmap_device_find_handle(IPC_GET_ARG1(*icall)); |
/* |
* Device not found. |
*/ |
if (device == NULL) { |
if (NULL == device) { |
ipc_answer_0(iid, ENOENT); |
return; |
} |
ipc_answer_0(iid, EOK); |
name_size = strlen(device->name); |
/* FIXME: |
we have no channel from DEVMAP to client -> |
sending must be initiated by client |
int rc = ipc_data_write_send(phone, device->name, name_size); |
if (rc != EOK) { |
async_wait_for(req, NULL); |
return rc; |
} |
ipc_answer_0(iid, EOK); |
size_t name_size = strlen(device->name); |
/* FIXME: |
* We have no channel from DEVMAP to client, therefore |
* sending must be initiated by client. |
* |
* int rc = ipc_data_write_send(phone, device->name, name_size); |
* if (rc != EOK) { |
* async_wait_for(req, NULL); |
* return rc; |
* } |
*/ |
*/ |
/* TODO: send name in response */ |
return; |
} |
/** Handle connection with device driver. |
* |
*/ |
static void devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection_driver(ipc_callid_t iid, ipc_call_t *icall) |
{ |
/* Accept connection */ |
ipc_answer_0(iid, EOK); |
ipc_callid_t callid; |
ipc_call_t call; |
bool cont = true; |
devmap_driver_t *driver = NULL; |
ipc_answer_0(iid, EOK); |
devmap_driver_register(&driver); |
if (NULL == driver) |
if (NULL == driver) { |
printf("DEVMAP: driver registration failed.\n"); |
return; |
} |
bool cont = true; |
while (cont) { |
ipc_call_t call; |
ipc_callid_t callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
printf("DEVMAP: connection hung up.\n"); |
cont = false; |
/* Exit thread */ |
continue; |
continue; /* Exit thread */ |
case DEVMAP_DRIVER_UNREGISTER: |
if (NULL == driver) |
printf("DEVMAP: unregister driver.\n"); |
if (NULL == driver) { |
printf("DEVMAP: driver was not registered!\n"); |
ipc_answer_0(callid, ENOENT); |
else |
} else { |
ipc_answer_0(callid, EOK); |
} |
break; |
case DEVMAP_DEVICE_REGISTER: |
/* Register one instance of device */ |
624,40 → 630,46 |
devmap_get_handle(callid, &call); |
break; |
default: |
if (!(callid & IPC_CALLID_NOTIFICATION)) |
if (!(callid & IPC_CALLID_NOTIFICATION)) { |
ipc_answer_0(callid, ENOENT); |
} |
} |
} |
if (NULL != driver) { |
/* |
/* |
* Unregister the device driver and all its devices. |
*/ |
devmap_driver_unregister(driver); |
driver = NULL; |
} |
} |
/** Handle connection with device client. |
* |
*/ |
static void devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection_client(ipc_callid_t iid, ipc_call_t *icall) |
{ |
/* Accept connection */ |
ipc_answer_0(iid, EOK); |
ipc_callid_t callid; |
ipc_call_t call; |
bool cont = true; |
ipc_answer_0(iid, EOK); /* Accept connection */ |
while (cont) { |
ipc_call_t call; |
ipc_callid_t callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
printf("DEVMAP: connection hung up.\n"); |
cont = false; |
/* Exit thread */ |
continue; |
continue; /* Exit thread */ |
case DEVMAP_DEVICE_GET_HANDLE: |
devmap_get_handle(callid, &call); |
devmap_get_handle(callid, &call); |
break; |
case DEVMAP_DEVICE_GET_NAME: |
/* TODO */ |
664,19 → 676,24 |
devmap_get_name(callid, &call); |
break; |
default: |
if (!(callid & IPC_CALLID_NOTIFICATION)) |
if (!(callid & IPC_CALLID_NOTIFICATION)) { |
ipc_answer_0(callid, ENOENT); |
} |
} |
} |
} |
/** Function for handling connections to devmap |
/** Function for handling connections to devmap |
* |
*/ |
static void devmap_connection(ipc_callid_t iid, ipc_call_t *icall) |
static void |
devmap_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
/* Select interface */ |
switch ((ipcarg_t) (IPC_GET_ARG1(*icall))) { |
printf("DEVMAP: new connection.\n"); |
/* Select interface */ |
switch ((ipcarg_t)(IPC_GET_ARG1(*icall))) { |
case DEVMAP_DRIVER: |
devmap_connection_driver(iid, icall); |
break; |
684,13 → 701,21 |
devmap_connection_client(iid, icall); |
break; |
case DEVMAP_CONNECT_TO_DEVICE: |
/* Connect client to selected device */ |
/* Connect client to selected device */ |
printf("DEVMAP: connect to device %d.\n", |
IPC_GET_ARG2(*icall)); |
devmap_forward(iid, icall); |
break; |
default: |
/* No such interface */ |
ipc_answer_0(iid, ENOENT); |
ipc_answer_0(iid, ENOENT); /* No such interface */ |
printf("DEVMAP: Unknown interface %u.\n", |
(ipcarg_t)(IPC_GET_ARG1(*icall))); |
} |
/* Cleanup */ |
printf("DEVMAP: connection closed.\n"); |
return; |
} |
/** |
698,24 → 723,23 |
*/ |
int main(int argc, char *argv[]) |
{ |
printf(NAME ": HelenOS Device Mapper\n"); |
ipcarg_t phonead; |
printf("DEVMAP: HelenOS device mapper.\n"); |
if (devmap_init() != 0) { |
printf(NAME ": Error while initializing service\n"); |
printf("Error while initializing DEVMAP service.\n"); |
return -1; |
} |
/* Set a handler of incomming connections */ |
/* Set a handler of incomming connections */ |
async_set_client_connection(devmap_connection); |
/* Register device mapper at naming service */ |
ipcarg_t phonead; |
if (ipc_connect_to_me(PHONE_NS, SERVICE_DEVMAP, 0, 0, &phonead) != 0) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
} |
723,3 → 747,4 |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/devmap/devmap.h |
---|
0,0 → 1,99 |
/* |
* Copyright (c) 2007 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup devmap |
* @{ |
*/ |
#ifndef DEVMAP_DEVMAP_H_ |
#define DEVMAP_DEVMAP_H_ |
#include <ipc/ipc.h> |
#include <libadt/list.h> |
#define DEVMAP_NAME_MAXLEN 512 |
typedef enum { |
DEVMAP_DRIVER_REGISTER = IPC_FIRST_USER_METHOD, |
DEVMAP_DRIVER_UNREGISTER, |
DEVMAP_DEVICE_REGISTER, |
DEVMAP_DEVICE_UNREGISTER, |
DEVMAP_DEVICE_GET_NAME, |
DEVMAP_DEVICE_GET_HANDLE |
} devmap_request_t; |
/** Representation of device driver. |
* Each driver is responsible for a set of devices. |
*/ |
typedef struct { |
/** Pointers to previous and next drivers in linked list */ |
link_t drivers; |
/** Pointer to the linked list of devices controlled by |
* this driver */ |
link_t devices; |
/** Phone asociated with this driver */ |
ipcarg_t phone; |
/** Device driver name */ |
char *name; |
/** Futex for list of devices owned by this driver */ |
atomic_t devices_futex; |
} devmap_driver_t; |
/** Info about registered device |
* |
*/ |
typedef struct { |
/** Pointer to the previous and next device in the list of all devices */ |
link_t devices; |
/** Pointer to the previous and next device in the list of devices |
owned by one driver */ |
link_t driver_devices; |
/** Unique device identifier */ |
int handle; |
/** Device name */ |
char *name; |
/** Device driver handling this device */ |
devmap_driver_t *driver; |
} devmap_device_t; |
/** Interface provided by devmap. |
* Every process that connects to devmap must ask one of following |
* interfaces otherwise connection will be refused. |
*/ |
typedef enum { |
/** Connect as device driver */ |
DEVMAP_DRIVER = 1, |
/** Connect as client */ |
DEVMAP_CLIENT, |
/** Create new connection to instance of device that |
* is specified by second argument of call. */ |
DEVMAP_CONNECT_TO_DEVICE |
} devmap_interface_t; |
#endif |
/branches/dd/uspace/srv/devmap/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../libipc/include |
45,30 → 44,28 |
SOURCES = \ |
devmap.c |
CFLAGS += -D$(UARCH) |
CFLAGS += -D$(ARCH) |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/ns/ns.c |
---|
28,11 → 28,11 |
/** @addtogroup ns |
* @{ |
*/ |
*/ |
/** |
* @file ns.c |
* @brief Naming service for HelenOS IPC. |
* @file ns.c |
* @brief Naming service for HelenOS IPC. |
*/ |
40,7 → 40,6 |
#include <ipc/ns.h> |
#include <ipc/services.h> |
#include <stdio.h> |
#include <bool.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <errno.h> |
48,24 → 47,17 |
#include <libadt/list.h> |
#include <libadt/hash_table.h> |
#include <sysinfo.h> |
#include <loader/loader.h> |
#include <ddi.h> |
#include <as.h> |
#define NAME "ns" |
#define NAME "NS" |
#define NS_HASH_TABLE_CHAINS 20 |
#define NS_HASH_TABLE_CHAINS 20 |
static int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call); |
static void connect_to_service(ipcarg_t service, ipc_call_t *call, |
static int connect_to_service(ipcarg_t service, ipc_call_t *call, |
ipc_callid_t callid); |
void register_clonable(ipcarg_t service, ipcarg_t phone, ipc_call_t *call, |
ipc_callid_t callid); |
void connect_to_clonable(ipcarg_t service, ipc_call_t *call, |
ipc_callid_t callid); |
/* Static functions implementing NS hash table operations. */ |
static hash_index_t ns_hash(unsigned long *key); |
static int ns_compare(unsigned long *key, hash_count_t keys, link_t *item); |
84,46 → 76,19 |
/** NS hash table item. */ |
typedef struct { |
link_t link; |
ipcarg_t service; /**< Number of the service. */ |
ipcarg_t phone; /**< Phone registered with the service. */ |
ipcarg_t in_phone_hash; /**< Incoming phone hash. */ |
ipcarg_t service; /**< Number of the service. */ |
ipcarg_t phone; /**< Phone registered with the service. */ |
ipcarg_t in_phone_hash; /**< Incoming phone hash. */ |
} hashed_service_t; |
/** Pending connection structure. */ |
typedef struct { |
link_t link; |
ipcarg_t service; /**< Number of the service. */ |
ipc_callid_t callid; /**< Call ID waiting for the connection */ |
ipcarg_t arg2; /**< Second argument */ |
ipcarg_t arg3; /**< Third argument */ |
} pending_req_t; |
static link_t pending_req; |
/** Request for connection to a clonable service. */ |
typedef struct { |
link_t link; |
ipcarg_t service; |
ipc_call_t call; |
ipc_callid_t callid; |
} cs_req_t; |
/** List of clonable-service connection requests. */ |
static link_t cs_req; |
static void *clockaddr = NULL; |
static void *klogaddr = NULL; |
/** Return true if @a service is clonable. */ |
static bool service_clonable(int service) |
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, |
void **addr) |
{ |
return (service == SERVICE_LOAD); |
} |
void *ph_addr; |
static void get_as_area(ipc_callid_t callid, ipc_call_t *call, char *name, void **addr) |
{ |
void *ph_addr; |
if (!*addr) { |
ph_addr = (void *) sysinfo_value(name); |
if (!ph_addr) { |
131,76 → 96,36 |
return; |
} |
*addr = as_get_mappable_page(PAGE_SIZE); |
if (physmem_map(ph_addr, *addr, 1, |
AS_AREA_READ | AS_AREA_CACHEABLE) != 0) { |
ipc_answer_0(callid, ENOENT); |
return; |
} |
physmem_map(ph_addr, *addr, 1, |
AS_AREA_READ | AS_AREA_CACHEABLE); |
} |
ipc_answer_2(callid, EOK, (ipcarg_t) *addr, AS_AREA_READ); |
} |
/** Process pending connection requests */ |
static void process_pending_req() |
int main(int argc, char **argv) |
{ |
link_t *cur; |
ipc_call_t call; |
ipc_callid_t callid; |
loop: |
for (cur = pending_req.next; cur != &pending_req; cur = cur->next) { |
pending_req_t *pr = list_get_instance(cur, pending_req_t, link); |
unsigned long keys[3] = { |
pr->service, |
0, |
0 |
}; |
link_t *link = hash_table_find(&ns_hash_table, keys); |
if (!link) |
continue; |
hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); |
ipcarg_t retval = ipc_forward_fast(pr->callid, hs->phone, |
pr->arg2, pr->arg3, 0, IPC_FF_NONE); |
if (!(pr->callid & IPC_CALLID_NOTIFICATION)) |
ipc_answer_0(pr->callid, retval); |
list_remove(cur); |
free(pr); |
goto loop; |
} |
} |
ipcarg_t retval; |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS IPC Naming Service\n"); |
if (!hash_table_create(&ns_hash_table, NS_HASH_TABLE_CHAINS, 3, |
&ns_hash_table_ops)) { |
printf(NAME ": No memory available for services\n"); |
return ENOMEM; |
} |
list_initialize(&pending_req); |
list_initialize(&cs_req); |
printf(NAME ": Accepting connections\n"); |
while (true) { |
process_pending_req(); |
ipc_call_t call; |
ipc_callid_t callid = ipc_wait_for_call(&call); |
ipcarg_t retval; |
while (1) { |
callid = ipc_wait_for_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_SHARE_IN: |
switch (IPC_GET_ARG3(call)) { |
case SERVICE_MEM_REALTIME: |
get_as_area(callid, &call, "clock.faddr", &clockaddr); |
get_as_area(callid, &call, "clock.faddr", |
&clockaddr); |
break; |
case SERVICE_MEM_KLOG: |
get_as_area(callid, &call, "klog.faddr", &klogaddr); |
get_as_area(callid, &call, "klog.faddr", |
&klogaddr); |
break; |
default: |
ipc_answer_0(callid, ENOENT); |
213,50 → 138,33 |
/* |
* Server requests service registration. |
*/ |
if (service_clonable(IPC_GET_ARG1(call))) { |
register_clonable(IPC_GET_ARG1(call), |
IPC_GET_ARG5(call), &call, callid); |
continue; |
} else { |
retval = register_service(IPC_GET_ARG1(call), |
IPC_GET_ARG5(call), &call); |
} |
retval = register_service(IPC_GET_ARG1(call), |
IPC_GET_ARG5(call), &call); |
break; |
case IPC_M_CONNECT_ME_TO: |
/* |
* Client requests to be connected to a service. |
*/ |
if (service_clonable(IPC_GET_ARG1(call))) { |
connect_to_clonable(IPC_GET_ARG1(call), |
&call, callid); |
continue; |
} else { |
connect_to_service(IPC_GET_ARG1(call), &call, |
callid); |
continue; |
} |
retval = connect_to_service(IPC_GET_ARG1(call), &call, |
callid); |
break; |
default: |
retval = ENOENT; |
break; |
} |
if (!(callid & IPC_CALLID_NOTIFICATION)) |
if (!(callid & IPC_CALLID_NOTIFICATION)) { |
ipc_answer_0(callid, retval); |
} |
} |
/* Not reached */ |
return 0; |
} |
/** Register service. |
* |
* @param service Service to be registered. |
* @param phone Phone to be used for connections to the service. |
* @param call Pointer to call structure. |
* @param phone Phone to be used for connections to the service. |
* @param call Pointer to call structure. |
* |
* @return Zero on success or a value from @ref errno.h. |
* |
*/ |
int register_service(ipcarg_t service, ipcarg_t phone, ipc_call_t *call) |
{ |
265,20 → 173,23 |
call->in_phone_hash, |
0 |
}; |
if (hash_table_find(&ns_hash_table, keys)) |
hashed_service_t *hs; |
if (hash_table_find(&ns_hash_table, keys)) { |
return EEXISTS; |
hashed_service_t *hs = (hashed_service_t *) malloc(sizeof(hashed_service_t)); |
if (!hs) |
} |
hs = (hashed_service_t *) malloc(sizeof(hashed_service_t)); |
if (!hs) { |
return ENOMEM; |
} |
link_initialize(&hs->link); |
hs->service = service; |
hs->phone = phone; |
hs->in_phone_hash = call->in_phone_hash; |
hash_table_insert(&ns_hash_table, keys, &hs->link); |
return 0; |
} |
285,135 → 196,36 |
/** Connect client to service. |
* |
* @param service Service to be connected to. |
* @param call Pointer to call structure. |
* @param callid Call ID of the request. |
* @param call Pointer to call structure. |
* @param callid Call ID of the request. |
* |
* @return Zero on success or a value from @ref errno.h. |
* |
*/ |
void connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid) |
int connect_to_service(ipcarg_t service, ipc_call_t *call, ipc_callid_t callid) |
{ |
ipcarg_t retval; |
unsigned long keys[3] = { |
service, |
0, |
0 |
}; |
link_t *link = hash_table_find(&ns_hash_table, keys); |
if (!link) { |
if (IPC_GET_ARG4(*call) & IPC_FLAG_BLOCKING) { |
/* Blocking connection, add to pending list */ |
pending_req_t *pr = (pending_req_t *) malloc(sizeof(pending_req_t)); |
if (!pr) { |
retval = ENOMEM; |
goto out; |
} |
unsigned long keys[3] = { service, 0, 0 }; |
link_t *hlp; |
hashed_service_t *hs; |
pr->service = service; |
pr->callid = callid; |
pr->arg2 = IPC_GET_ARG2(*call); |
pr->arg3 = IPC_GET_ARG3(*call); |
list_append(&pr->link, &pending_req); |
return; |
} |
retval = ENOENT; |
goto out; |
hlp = hash_table_find(&ns_hash_table, keys); |
if (!hlp) { |
return ENOENT; |
} |
hashed_service_t *hs = hash_table_get_instance(link, hashed_service_t, link); |
retval = ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), |
IPC_GET_ARG3(*call), 0, IPC_FF_NONE); |
out: |
if (!(callid & IPC_CALLID_NOTIFICATION)) |
ipc_answer_0(callid, retval); |
hs = hash_table_get_instance(hlp, hashed_service_t, link); |
return ipc_forward_fast(callid, hs->phone, IPC_GET_ARG2(*call), |
IPC_GET_ARG3(*call), 0, IPC_FF_NONE); |
} |
/** Register clonable service. |
* |
* @param service Service to be registered. |
* @param phone Phone to be used for connections to the service. |
* @param call Pointer to call structure. |
* |
*/ |
void register_clonable(ipcarg_t service, ipcarg_t phone, ipc_call_t *call, |
ipc_callid_t callid) |
{ |
if (list_empty(&cs_req)) { |
/* There was no pending connection request. */ |
printf(NAME ": Unexpected clonable server.\n"); |
ipc_answer_0(callid, EBUSY); |
return; |
} |
cs_req_t *csr = list_get_instance(cs_req.next, cs_req_t, link); |
list_remove(&csr->link); |
/* Currently we can only handle a single type of clonable service. */ |
assert(csr->service == SERVICE_LOAD); |
ipc_answer_0(callid, EOK); |
int rc = ipc_forward_fast(csr->callid, phone, IPC_GET_ARG2(csr->call), |
IPC_GET_ARG3(csr->call), 0, IPC_FF_NONE); |
free(csr); |
} |
/** Connect client to clonable service. |
* |
* @param service Service to be connected to. |
* @param call Pointer to call structure. |
* @param callid Call ID of the request. |
* |
* @return Zero on success or a value from @ref errno.h. |
* |
*/ |
void connect_to_clonable(ipcarg_t service, ipc_call_t *call, |
ipc_callid_t callid) |
{ |
assert(service == SERVICE_LOAD); |
cs_req_t *csr = malloc(sizeof(cs_req_t)); |
if (csr == NULL) { |
ipc_answer_0(callid, ENOMEM); |
return; |
} |
/* Spawn a loader. */ |
int rc = loader_spawn("loader"); |
if (rc < 0) { |
free(csr); |
ipc_answer_0(callid, rc); |
return; |
} |
csr->service = service; |
csr->call = *call; |
csr->callid = callid; |
/* |
* We can forward the call only after the server we spawned connects |
* to us. Meanwhile we might need to service more connection requests. |
* Thus we store the call in a queue. |
*/ |
list_append(&csr->link, &cs_req); |
} |
/** Compute hash index into NS hash table. |
* |
* @param key Pointer keys. However, only the first key (i.e. service number) |
* is used to compute the hash index. |
* |
* is used to compute the hash index. |
* @return Hash index corresponding to key[0]. |
* |
*/ |
hash_index_t ns_hash(unsigned long *key) |
{ |
assert(key); |
return (*key % NS_HASH_TABLE_CHAINS); |
return *key % NS_HASH_TABLE_CHAINS; |
} |
/** Compare a key with hashed item. |
424,20 → 236,20 |
* value. Note that this is close to being classified |
* as a nasty hack. |
* |
* @param key Array of keys. |
* @param key Array of keys. |
* @param keys Must be lesser or equal to 3. |
* @param item Pointer to a hash table item. |
* |
* @return Non-zero if the key matches the item, zero otherwise. |
* |
*/ |
int ns_compare(unsigned long key[], hash_count_t keys, link_t *item) |
{ |
hashed_service_t *hs; |
assert(key); |
assert(keys <= 3); |
assert(item); |
hashed_service_t *hs = hash_table_get_instance(item, hashed_service_t, link); |
hs = hash_table_get_instance(item, hashed_service_t, link); |
if (keys == 2) |
return key[1] == hs->in_phone_hash; |
448,7 → 260,6 |
/** Perform actions after removal of item from the hash table. |
* |
* @param item Item that was removed from the hash table. |
* |
*/ |
void ns_remove(link_t *item) |
{ |
456,6 → 267,6 |
free(hash_table_get_instance(item, hashed_service_t, link)); |
} |
/** |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/ns/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
47,24 → 46,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld -e __entry_driver $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/fb/serial_console.c |
---|
File deleted |
/branches/dd/uspace/srv/fb/serial_console.h |
---|
File deleted |
/branches/dd/uspace/srv/fb/ski.c |
---|
File deleted |
/branches/dd/uspace/srv/fb/ski.h |
---|
File deleted |
/branches/dd/uspace/srv/fb/msim.c |
---|
File deleted |
/branches/dd/uspace/srv/fb/sgcn.c |
---|
File deleted |
/branches/dd/uspace/srv/fb/msim.h |
---|
File deleted |
/branches/dd/uspace/srv/fb/sgcn.h |
---|
File deleted |
\ No newline at end of file |
/branches/dd/uspace/srv/fb/fb.c |
---|
1,5 → 1,4 |
/* |
* Copyright (c) 2008 Martin Decky |
* Copyright (c) 2006 Jakub Vana |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
33,7 → 32,7 |
* @brief HelenOS graphical framebuffer. |
* @ingroup fbs |
* @{ |
*/ |
*/ |
/** @file |
*/ |
51,8 → 50,6 |
#include <ipc/services.h> |
#include <kernel/errno.h> |
#include <kernel/genarch/fb/visuals.h> |
#include <console/color.h> |
#include <console/style.h> |
#include <async.h> |
#include <bool.h> |
65,433 → 62,427 |
#include "pointer.xbm" |
#include "pointer_mask.xbm" |
#define DEFAULT_BGCOLOR 0xf0f0f0 |
#define DEFAULT_FGCOLOR 0x000000 |
#define DEFAULT_BGCOLOR 0xf0f0f0 |
#define DEFAULT_FGCOLOR 0x0 |
#define MAX_ANIM_LEN 8 |
#define MAX_ANIMATIONS 4 |
#define MAX_PIXMAPS 256 /**< Maximum number of saved pixmaps */ |
#define MAX_VIEWPORTS 128 /**< Viewport is a rectangular area on the screen */ |
/***************************************************************/ |
/* Pixel specific fuctions */ |
/** Function to render a pixel from a RGB value. */ |
typedef void (*rgb_conv_t)(void *, uint32_t); |
typedef void (*conv2scr_fn_t)(void *, int); |
typedef int (*conv2rgb_fn_t)(void *); |
/** Function to draw a glyph. */ |
typedef void (*dg_t)(unsigned int x, unsigned int y, bool cursor, |
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
struct { |
uint8_t *fbaddress; |
struct { |
uint8_t *fb_addr; |
unsigned int xres; |
unsigned int yres; |
unsigned int scanline; |
unsigned int glyphscanline; |
unsigned int pixelbytes; |
unsigned int glyphbytes; |
rgb_conv_t rgb_conv; |
unsigned int invert_colors; |
conv2scr_fn_t rgb2scr; |
conv2rgb_fn_t scr2rgb; |
} screen; |
/** Backbuffer character cell. */ |
typedef struct { |
uint8_t glyph; |
uint32_t fg_color; |
uint32_t bg_color; |
} bb_cell_t; |
int initialized; |
unsigned int x, y; |
unsigned int width, height; |
typedef struct { |
bool initialized; |
unsigned int x; |
unsigned int y; |
unsigned int width; |
unsigned int height; |
/* Text support in window */ |
unsigned int cols; |
unsigned int rows; |
/* |
* Style and glyphs for text printing |
*/ |
/** Current attributes. */ |
attr_rgb_t attr; |
/** Pre-rendered mask for rendering glyphs. Different viewports |
* might use different drawing functions depending on whether their |
* scanlines are aligned on a word boundary.*/ |
uint8_t *glyphs; |
uint8_t *bgpixel; |
/** Glyph drawing function for this viewport. */ |
dg_t dglyph; |
unsigned int rows, cols; |
/* Style for text printing */ |
style_t style; |
/* Auto-cursor position */ |
bool cursor_active; |
unsigned int cur_col; |
unsigned int cur_row; |
bool cursor_shown; |
/* Back buffer */ |
bb_cell_t *backbuf; |
unsigned int bbsize; |
int cursor_active, cur_col, cur_row; |
int cursor_shown; |
/* Double buffering */ |
uint8_t *dbdata; |
unsigned int dboffset; |
unsigned int paused; |
} viewport_t; |
#define MAX_ANIM_LEN 8 |
#define MAX_ANIMATIONS 4 |
typedef struct { |
bool initialized; |
bool enabled; |
int initialized; |
int enabled; |
unsigned int vp; |
unsigned int pos; |
unsigned int animlen; |
unsigned int pixmaps[MAX_ANIM_LEN]; |
} animation_t; |
static animation_t animations[MAX_ANIMATIONS]; |
static bool anims_enabled; |
static int anims_enabled; |
/** Maximum number of saved pixmaps |
* Pixmap is a saved rectangle |
*/ |
#define MAX_PIXMAPS 256 |
typedef struct { |
unsigned int width; |
unsigned int height; |
uint8_t *data; |
} pixmap_t; |
static pixmap_t pixmaps[MAX_PIXMAPS]; |
static pixmap_t pixmaps[MAX_PIXMAPS]; |
/* Viewport is a rectangular area on the screen */ |
#define MAX_VIEWPORTS 128 |
static viewport_t viewports[128]; |
static bool client_connected = false; /**< Allow only 1 connection */ |
/* Allow only 1 connection */ |
static int client_connected = 0; |
static uint32_t color_table[16] = { |
[COLOR_BLACK] = 0x000000, |
[COLOR_BLUE] = 0x0000f0, |
[COLOR_GREEN] = 0x00f000, |
[COLOR_CYAN] = 0x00f0f0, |
[COLOR_RED] = 0xf00000, |
[COLOR_MAGENTA] = 0xf000f0, |
[COLOR_YELLOW] = 0xf0f000, |
[COLOR_WHITE] = 0xf0f0f0, |
#define RED(x, bits) ((x >> (16 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
[8 + COLOR_BLACK] = 0x000000, |
[8 + COLOR_BLUE] = 0x0000ff, |
[8 + COLOR_GREEN] = 0x00ff00, |
[8 + COLOR_CYAN] = 0x00ffff, |
[8 + COLOR_RED] = 0xff0000, |
[8 + COLOR_MAGENTA] = 0xff00ff, |
[8 + COLOR_YELLOW] = 0xffff00, |
[8 + COLOR_WHITE] = 0xffffff, |
}; |
#define COL_WIDTH 8 |
#define ROW_BYTES (screen.scanline * FONT_SCANLINES) |
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a); |
static int rgb_from_style(attr_rgb_t *rgb, int style); |
static int rgb_from_idx(attr_rgb_t *rgb, ipcarg_t fg_color, |
ipcarg_t bg_color, ipcarg_t flags); |
#define POINTPOS(x, y) ((y) * screen.scanline + (x) * screen.pixelbytes) |
static int fb_set_color(viewport_t *vport, ipcarg_t fg_color, |
ipcarg_t bg_color, ipcarg_t attr); |
static inline int COLOR(int color) |
{ |
return screen.invert_colors ? ~color : color; |
} |
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, |
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
static void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, |
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color); |
/* Conversion routines between different color representations */ |
static void |
rgb_byte0888(void *dst, int rgb) |
{ |
*(int *)dst = rgb; |
} |
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, |
unsigned int row); |
static int |
byte0888_rgb(void *src) |
{ |
return (*(int *)src) & 0xffffff; |
} |
static void |
bgr_byte0888(void *dst, int rgb) |
{ |
*((uint32_t *) dst) = BLUE(rgb, 8) << 16 | GREEN(rgb, 8) << 8 | |
RED(rgb, 8); |
} |
#define RED(x, bits) ((x >> (8 + 8 + 8 - bits)) & ((1 << bits) - 1)) |
#define GREEN(x, bits) ((x >> (8 + 8 - bits)) & ((1 << bits) - 1)) |
#define BLUE(x, bits) ((x >> (8 - bits)) & ((1 << bits) - 1)) |
static int |
byte0888_bgr(void *src) |
{ |
int color = *(uint32_t *)(src); |
return ((color & 0xff) << 16) | (((color >> 8) & 0xff) << 8) | |
((color >> 16) & 0xff); |
} |
#define COL2X(col) ((col) * FONT_WIDTH) |
#define ROW2Y(row) ((row) * FONT_SCANLINES) |
static void |
rgb_byte888(void *dst, int rgb) |
{ |
uint8_t *scr = dst; |
#if defined(FB_INVERT_ENDIAN) |
scr[0] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[2] = BLUE(rgb, 8); |
#else |
scr[2] = RED(rgb, 8); |
scr[1] = GREEN(rgb, 8); |
scr[0] = BLUE(rgb, 8); |
#endif |
} |
#define X2COL(x) ((x) / FONT_WIDTH) |
#define Y2ROW(y) ((y) / FONT_SCANLINES) |
static int |
byte888_rgb(void *src) |
{ |
uint8_t *scr = src; |
#if defined(FB_INVERT_ENDIAN) |
return scr[0] << 16 | scr[1] << 8 | scr[2]; |
#else |
return scr[2] << 16 | scr[1] << 8 | scr[0]; |
#endif |
} |
#define FB_POS(x, y) ((y) * screen.scanline + (x) * screen.pixelbytes) |
#define BB_POS(vport, col, row) ((row) * vport->cols + (col)) |
#define GLYPH_POS(glyph, y, cursor) (((glyph) + (cursor) * FONT_GLYPHS) * screen.glyphbytes + (y) * screen.glyphscanline) |
/** 16-bit depth (5:5:5) */ |
static void |
rgb_byte555(void *dst, int rgb) |
{ |
/* 5-bit, 5-bits, 5-bits */ |
*((uint16_t *)(dst)) = RED(rgb, 5) << 10 | GREEN(rgb, 5) << 5 | |
BLUE(rgb, 5); |
} |
/** 16-bit depth (5:5:5) */ |
static int |
byte555_rgb(void *src) |
{ |
int color = *(uint16_t *)(src); |
return (((color >> 10) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x1f) << (8 + 3)) | ((color & 0x1f) << 3); |
} |
/** ARGB 8:8:8:8 conversion |
* |
*/ |
static void rgb_0888(void *dst, uint32_t rgb) |
/** 16-bit depth (5:6:5) */ |
static void |
rgb_byte565(void *dst, int rgb) |
{ |
*((uint32_t *) dst) = rgb & 0xffffff; |
/* 5-bit, 6-bits, 5-bits */ |
*((uint16_t *)(dst)) = RED(rgb, 5) << 11 | GREEN(rgb, 6) << 5 | |
BLUE(rgb, 5); |
} |
/** 16-bit depth (5:6:5) */ |
static int |
byte565_rgb(void *src) |
{ |
int color = *(uint16_t *)(src); |
return (((color >> 11) & 0x1f) << (16 + 3)) | |
(((color >> 5) & 0x3f) << (8 + 2)) | ((color & 0x1f) << 3); |
} |
/** ABGR 8:8:8:8 conversion |
* |
*/ |
static void bgr_0888(void *dst, uint32_t rgb) |
/** Put pixel - 8-bit depth (3:2:3) */ |
static void |
rgb_byte8(void *dst, int rgb) |
{ |
*((uint32_t *) dst) |
= (BLUE(rgb, 8) << 16) | (GREEN(rgb, 8) << 8) | RED(rgb, 8); |
*(uint8_t *)dst = RED(rgb, 3) << 5 | GREEN(rgb, 2) << 3 | BLUE(rgb, 3); |
} |
/** RGB 8:8:8 conversion |
* |
*/ |
static void rgb_888(void *dst, uint32_t rgb) |
/** Return pixel color - 8-bit depth (3:2:3) */ |
static int |
byte8_rgb(void *src) |
{ |
((uint8_t *) dst)[0] = BLUE(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = RED(rgb, 8); |
int color = *(uint8_t *)src; |
return (((color >> 5) & 0x7) << (16 + 5)) | |
(((color >> 3) & 0x3) << (8 + 6)) | ((color & 0x7) << 5); |
} |
/** BGR 8:8:8 conversion |
/** Put pixel into viewport |
* |
* @param vport Viewport identification |
* @param x X coord relative to viewport |
* @param y Y coord relative to viewport |
* @param color RGB color |
*/ |
static void bgr_888(void *dst, uint32_t rgb) |
static void |
putpixel(viewport_t *vport, unsigned int x, unsigned int y, int color) |
{ |
((uint8_t *) dst)[0] = RED(rgb, 8); |
((uint8_t *) dst)[1] = GREEN(rgb, 8); |
((uint8_t *) dst)[2] = BLUE(rgb, 8); |
} |
int dx = vport->x + x; |
int dy = vport->y + y; |
if (! (vport->paused && vport->dbdata)) |
(*screen.rgb2scr)(&screen.fbaddress[POINTPOS(dx,dy)], |
COLOR(color)); |
/** RGB 5:5:5 conversion |
* |
*/ |
static void rgb_555(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 10) | (GREEN(rgb, 5) << 5) | BLUE(rgb, 5); |
if (vport->dbdata) { |
int dline = (y + vport->dboffset) % vport->height; |
int doffset = screen.pixelbytes * (dline * vport->width + x); |
(*screen.rgb2scr)(&vport->dbdata[doffset], COLOR(color)); |
} |
} |
/** Get pixel from viewport */ |
static int |
getpixel(viewport_t *vport, unsigned int x, unsigned int y) |
{ |
int dx = vport->x + x; |
int dy = vport->y + y; |
/** RGB 5:6:5 conversion |
* |
*/ |
static void rgb_565(void *dst, uint32_t rgb) |
{ |
*((uint16_t *) dst) |
= (RED(rgb, 5) << 11) | (GREEN(rgb, 6) << 5) | BLUE(rgb, 5); |
return COLOR((*screen.scr2rgb)(&screen.fbaddress[POINTPOS(dx, dy)])); |
} |
/** RGB 3:2:3 |
* |
*/ |
static void rgb_323(void *dst, uint32_t rgb) |
static inline void |
putpixel_mem(char *mem, unsigned int x, unsigned int y, int color) |
{ |
*((uint8_t *) dst) |
= ~((RED(rgb, 3) << 5) | (GREEN(rgb, 2) << 3) | BLUE(rgb, 3)); |
(*screen.rgb2scr)(&mem[POINTPOS(x, y)], COLOR(color)); |
} |
/** Draw a filled rectangle. |
* |
* @note Need real implementation that does not access VRAM twice. |
*/ |
static void draw_filled_rect(unsigned int x0, unsigned int y0, unsigned int x1, |
unsigned int y1, uint32_t color) |
static void |
draw_rectangle(viewport_t *vport, unsigned int sx, unsigned int sy, |
unsigned int width, unsigned int height, int color) |
{ |
unsigned int x, y; |
unsigned int copy_bytes; |
static void *tmpline; |
uint8_t *sp, *dp; |
uint8_t cbuf[4]; |
if (!tmpline) |
tmpline = malloc(screen.scanline * screen.pixelbytes); |
if (y0 >= y1 || x0 >= x1) return; |
screen.rgb_conv(cbuf, color); |
/* Clear first line */ |
for (x = 0; x < width; x++) |
putpixel_mem(tmpline, x, 0, color); |
sp = &screen.fb_addr[FB_POS(x0, y0)]; |
dp = sp; |
/* Draw the first line. */ |
for (x = x0; x < x1; x++) { |
memcpy(dp, cbuf, screen.pixelbytes); |
dp += screen.pixelbytes; |
if (!vport->paused) { |
/* Recompute to screen coords */ |
sx += vport->x; |
sy += vport->y; |
/* Copy the rest */ |
for (y = sy;y < sy+height; y++) |
memcpy(&screen.fbaddress[POINTPOS(sx,y)], tmpline, |
screen.pixelbytes * width); |
} |
if (vport->dbdata) { |
for (y = sy; y < sy + height; y++) { |
int rline = (y + vport->dboffset) % vport->height; |
int rpos = (rline * vport->width + sx) * |
screen.pixelbytes; |
memcpy(&vport->dbdata[rpos], tmpline, |
screen.pixelbytes * width); |
} |
} |
dp = sp + screen.scanline; |
copy_bytes = (x1 - x0) * screen.pixelbytes; |
} |
/* Draw the remaining lines by copying. */ |
for (y = y0 + 1; y < y1; y++) { |
memcpy(dp, sp, copy_bytes); |
dp += screen.scanline; |
} |
/** Fill viewport with background color */ |
static void |
clear_port(viewport_t *vport) |
{ |
draw_rectangle(vport, 0, 0, vport->width, vport->height, |
vport->style.bg_color); |
} |
/** Redraw viewport. |
/** Scroll unbuffered viewport up/down |
* |
* @param vport Viewport to redraw |
* |
* @param vport Viewport to scroll |
* @param lines Positive number - scroll up, negative - scroll down |
*/ |
static void vport_redraw(viewport_t *vport) |
static void |
scroll_port_nodb(viewport_t *vport, int lines) |
{ |
unsigned int row, col; |
int y; |
for (row = 0; row < vport->rows; row++) { |
for (col = 0; col < vport->cols; col++) { |
draw_vp_glyph(vport, false, col, row); |
} |
if (lines > 0) { |
for (y = vport->y; y < vport->y+vport->height - lines; y++) |
memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
&screen.fbaddress[POINTPOS(vport->x,y + lines)], |
screen.pixelbytes * vport->width); |
draw_rectangle(vport, 0, vport->height - lines, vport->width, |
lines, vport->style.bg_color); |
} else if (lines < 0) { |
lines = -lines; |
for (y = vport->y + vport->height-1; y >= vport->y + lines; y--) |
memcpy(&screen.fbaddress[POINTPOS(vport->x,y)], |
&screen.fbaddress[POINTPOS(vport->x,y - lines)], |
screen.pixelbytes * vport->width); |
draw_rectangle(vport, 0, 0, vport->width, lines, |
vport->style.bg_color); |
} |
} |
if (COL2X(vport->cols) < vport->width) { |
draw_filled_rect( |
vport->x + COL2X(vport->cols), vport->y, |
vport->x + vport->width, vport->y + vport->height, |
vport->attr.bg_color); |
} |
/** Refresh given viewport from double buffer */ |
static void |
refresh_viewport_db(viewport_t *vport) |
{ |
unsigned int y, srcy, srcoff, dsty, dstx; |
if (ROW2Y(vport->rows) < vport->height) { |
draw_filled_rect( |
vport->x, vport->y + ROW2Y(vport->rows), |
vport->x + vport->width, vport->y + vport->height, |
vport->attr.bg_color); |
for (y = 0; y < vport->height; y++) { |
srcy = (y + vport->dboffset) % vport->height; |
srcoff = (vport->width * srcy) * screen.pixelbytes; |
dstx = vport->x; |
dsty = vport->y + y; |
memcpy(&screen.fbaddress[POINTPOS(dstx,dsty)], |
&vport->dbdata[srcoff], vport->width * screen.pixelbytes); |
} |
} |
static void backbuf_clear(bb_cell_t *backbuf, size_t len, uint32_t fg_color, |
uint32_t bg_color) |
/** Scroll viewport that has double buffering enabled */ |
static void |
scroll_port_db(viewport_t *vport, int lines) |
{ |
unsigned i; |
++vport->paused; |
if (lines > 0) { |
draw_rectangle(vport, 0, 0, vport->width, lines, |
vport->style.bg_color); |
vport->dboffset += lines; |
vport->dboffset %= vport->height; |
} else if (lines < 0) { |
lines = -lines; |
draw_rectangle(vport, 0, vport->height-lines, vport->width, |
lines, vport->style.bg_color); |
for (i = 0; i < len; i++) { |
backbuf[i].glyph = 0; |
backbuf[i].fg_color = fg_color; |
backbuf[i].bg_color = bg_color; |
if (vport->dboffset < lines) |
vport->dboffset += vport->height; |
vport->dboffset -= lines; |
} |
--vport->paused; |
refresh_viewport_db(vport); |
} |
/** Clear viewport. |
* |
* @param vport Viewport to clear |
* |
*/ |
static void vport_clear(viewport_t *vport) |
/** Scrolls viewport given number of lines */ |
static void |
scroll_port(viewport_t *vport, int lines) |
{ |
backbuf_clear(vport->backbuf, vport->cols * vport->rows, |
vport->attr.fg_color, vport->attr.bg_color); |
vport_redraw(vport); |
if (vport->dbdata) |
scroll_port_db(vport, lines); |
else |
scroll_port_nodb(vport, lines); |
} |
/** Scroll viewport by the specified number of lines. |
* |
* @param vport Viewport to scroll |
* @param lines Number of lines to scroll |
* |
*/ |
static void vport_scroll(viewport_t *vport, int lines) |
static void |
invert_pixel(viewport_t *vport, unsigned int x, unsigned int y) |
{ |
unsigned int row, col; |
unsigned int x, y; |
uint8_t glyph; |
uint32_t fg_color; |
uint32_t bg_color; |
bb_cell_t *bbp, *xbp; |
putpixel(vport, x, y, ~getpixel(vport, x, y)); |
} |
/* |
* Redraw. |
*/ |
y = vport->y; |
for (row = 0; row < vport->rows; row++) { |
x = vport->x; |
for (col = 0; col < vport->cols; col++) { |
if ((row + lines >= 0) && (row + lines < vport->rows)) { |
xbp = &vport->backbuf[BB_POS(vport, col, row + lines)]; |
bbp = &vport->backbuf[BB_POS(vport, col, row)]; |
/***************************************************************/ |
/* Character-console functions */ |
glyph = xbp->glyph; |
fg_color = xbp->fg_color; |
bg_color = xbp->bg_color; |
/** Draw character at given position |
* |
* @param vport Viewport where the character is printed |
* @param sx Coordinates of top-left of the character |
* @param sy Coordinates of top-left of the character |
* @param style Color of the character |
* @param transparent If false, print background color |
*/ |
static void |
draw_glyph(viewport_t *vport,uint8_t glyph, unsigned int sx, unsigned int sy, |
style_t style, int transparent) |
{ |
int i; |
unsigned int y; |
unsigned int glline; |
if (bbp->glyph == glyph && |
bbp->fg_color == xbp->fg_color && |
bbp->bg_color == xbp->bg_color) { |
x += FONT_WIDTH; |
continue; |
} |
} else { |
glyph = 0; |
fg_color = vport->attr.fg_color; |
bg_color = vport->attr.bg_color; |
} |
(*vport->dglyph)(x, y, false, vport->glyphs, glyph, |
fg_color, bg_color); |
x += FONT_WIDTH; |
for (y = 0; y < FONT_SCANLINES; y++) { |
glline = fb_font[glyph * FONT_SCANLINES + y]; |
for (i = 0; i < 8; i++) { |
if (glline & (1 << (7 - i))) |
putpixel(vport, sx + i, sy + y, style.fg_color); |
else if (!transparent) |
putpixel(vport, sx + i, sy + y, style.bg_color); |
} |
y += FONT_SCANLINES; |
} |
/* |
* Scroll backbuffer. |
*/ |
if (lines > 0) { |
memmove(vport->backbuf, vport->backbuf + vport->cols * lines, |
vport->cols * (vport->rows - lines) * sizeof(bb_cell_t)); |
backbuf_clear(&vport->backbuf[BB_POS(vport, 0, vport->rows - lines)], |
vport->cols * lines, vport->attr.fg_color, vport->attr.bg_color); |
} else { |
memmove(vport->backbuf - vport->cols * lines, vport->backbuf, |
vport->cols * (vport->rows + lines) * sizeof(bb_cell_t)); |
backbuf_clear(vport->backbuf, - vport->cols * lines, |
vport->attr.fg_color, vport->attr.bg_color); |
} |
} |
/** Render glyphs |
* |
* Convert glyphs from device independent font |
* description to current visual representation. |
* |
* @param vport Viewport |
* |
*/ |
static void render_glyphs(viewport_t* vport) |
/** Invert character at given position */ |
static void |
invert_char(viewport_t *vport,unsigned int row, unsigned int col) |
{ |
unsigned int glyph; |
for (glyph = 0; glyph < FONT_GLYPHS; glyph++) { |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) { |
unsigned int x; |
for (x = 0; x < FONT_WIDTH; x++) { |
screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, false) + x * screen.pixelbytes], |
(fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
? 0xffffff : 0x000000); |
screen.rgb_conv(&vport->glyphs[GLYPH_POS(glyph, y, true) + x * screen.pixelbytes], |
(fb_font[glyph * FONT_SCANLINES + y] & (1 << (7 - x))) |
? 0x000000 : 0xffffff); |
} |
} |
} |
screen.rgb_conv(vport->bgpixel, vport->attr.bg_color); |
unsigned int x; |
unsigned int y; |
for (x = 0; x < COL_WIDTH; x++) |
for (y = 0; y < FONT_SCANLINES; y++) |
invert_pixel(vport, col * COL_WIDTH + x, row * |
FONT_SCANLINES + y); |
} |
/***************************************************************/ |
/* Stdout specific functions */ |
/** Create new viewport |
* |
* @param x Origin of the viewport (x). |
* @param y Origin of the viewport (y). |
* @param width Width of the viewport. |
* @param height Height of the viewport. |
* |
* @return New viewport number. |
* |
* @return New viewport number |
*/ |
static int vport_create(unsigned int x, unsigned int y, |
unsigned int width, unsigned int height) |
static int |
viewport_create(unsigned int x, unsigned int y,unsigned int width, |
unsigned int height) |
{ |
unsigned int i; |
int i; |
for (i = 0; i < MAX_VIEWPORTS; i++) { |
if (!viewports[i].initialized) |
break; |
498,124 → 489,75 |
} |
if (i == MAX_VIEWPORTS) |
return ELIMIT; |
unsigned int cols = width / FONT_WIDTH; |
unsigned int rows = height / FONT_SCANLINES; |
unsigned int bbsize = cols * rows * sizeof(bb_cell_t); |
unsigned int glyphsize = 2 * FONT_GLYPHS * screen.glyphbytes; |
unsigned int word_size = sizeof(unsigned long); |
bb_cell_t *backbuf = (bb_cell_t *) malloc(bbsize); |
if (!backbuf) |
return ENOMEM; |
uint8_t *glyphs = (uint8_t *) malloc(glyphsize); |
if (!glyphs) { |
free(backbuf); |
return ENOMEM; |
} |
uint8_t *bgpixel = (uint8_t *) malloc(screen.pixelbytes); |
if (!bgpixel) { |
free(glyphs); |
free(backbuf); |
return ENOMEM; |
} |
backbuf_clear(backbuf, cols * rows, DEFAULT_FGCOLOR, DEFAULT_BGCOLOR); |
memset(glyphs, 0, glyphsize); |
memset(bgpixel, 0, screen.pixelbytes); |
viewports[i].x = x; |
viewports[i].y = y; |
viewports[i].width = width; |
viewports[i].height = height; |
viewports[i].cols = cols; |
viewports[i].rows = rows; |
viewports[i].rows = height / FONT_SCANLINES; |
viewports[i].cols = width / COL_WIDTH; |
viewports[i].style.bg_color = DEFAULT_BGCOLOR; |
viewports[i].style.fg_color = DEFAULT_FGCOLOR; |
viewports[i].attr.bg_color = DEFAULT_BGCOLOR; |
viewports[i].attr.fg_color = DEFAULT_FGCOLOR; |
viewports[i].glyphs = glyphs; |
viewports[i].bgpixel = bgpixel; |
viewports[i].cur_col = 0; |
viewports[i].cur_row = 0; |
viewports[i].cursor_active = 0; |
/* |
* Conditions necessary to select aligned version: |
* |
* - word size is divisible by pixelbytes |
* - cell scanline size is divisible by word size |
* - cell scanlines are word-aligned |
*/ |
if ((word_size % screen.pixelbytes) == 0 && |
(FONT_WIDTH * screen.pixelbytes) % word_size == 0 && |
(x * screen.pixelbytes) % word_size == 0 && |
screen.scanline % word_size == 0) { |
viewports[i].initialized = 1; |
viewports[i].dglyph = draw_glyph_aligned; |
} else { |
viewports[i].dglyph = draw_glyph_fallback; |
} |
viewports[i].cur_col = 0; |
viewports[i].cur_row = 0; |
viewports[i].cursor_active = false; |
viewports[i].cursor_shown = false; |
viewports[i].bbsize = bbsize; |
viewports[i].backbuf = backbuf; |
viewports[i].initialized = true; |
render_glyphs(&viewports[i]); |
return i; |
} |
/** Initialize framebuffer as a chardev output device |
* |
* @param addr Address of the framebuffer |
* @param xres Screen width in pixels |
* @param yres Screen height in pixels |
* @param visual Bits per pixel (8, 16, 24, 32) |
* @param scan Bytes per one scanline |
* @param addr Address of theframebuffer |
* @param xres Screen width in pixels |
* @param yres Screen height in pixels |
* @param visual Bits per pixel (8, 16, 24, 32) |
* @param scan Bytes per one scanline |
* @param invert_colors Inverted colors. |
* |
*/ |
static bool screen_init(void *addr, unsigned int xres, unsigned int yres, |
unsigned int scan, unsigned int visual) |
static bool |
screen_init(void *addr, unsigned int xres, unsigned int yres, |
unsigned int scan, unsigned int visual, bool invert_colors) |
{ |
switch (visual) { |
case VISUAL_INDIRECT_8: |
screen.rgb_conv = rgb_323; |
screen.rgb2scr = rgb_byte8; |
screen.scr2rgb = byte8_rgb; |
screen.pixelbytes = 1; |
break; |
case VISUAL_RGB_5_5_5: |
screen.rgb_conv = rgb_555; |
screen.rgb2scr = rgb_byte555; |
screen.scr2rgb = byte555_rgb; |
screen.pixelbytes = 2; |
break; |
case VISUAL_RGB_5_6_5: |
screen.rgb_conv = rgb_565; |
screen.rgb2scr = rgb_byte565; |
screen.scr2rgb = byte565_rgb; |
screen.pixelbytes = 2; |
break; |
case VISUAL_RGB_8_8_8: |
screen.rgb_conv = rgb_888; |
screen.rgb2scr = rgb_byte888; |
screen.scr2rgb = byte888_rgb; |
screen.pixelbytes = 3; |
break; |
case VISUAL_BGR_8_8_8: |
screen.rgb_conv = bgr_888; |
screen.pixelbytes = 3; |
break; |
case VISUAL_RGB_8_8_8_0: |
screen.rgb_conv = rgb_888; |
screen.rgb2scr = rgb_byte888; |
screen.scr2rgb = byte888_rgb; |
screen.pixelbytes = 4; |
break; |
case VISUAL_RGB_0_8_8_8: |
screen.rgb_conv = rgb_0888; |
screen.rgb2scr = rgb_byte0888; |
screen.scr2rgb = byte0888_rgb; |
screen.pixelbytes = 4; |
break; |
case VISUAL_BGR_0_8_8_8: |
screen.rgb_conv = bgr_0888; |
screen.rgb2scr = bgr_byte0888; |
screen.scr2rgb = byte0888_bgr; |
screen.pixelbytes = 4; |
break; |
default: |
622,239 → 564,72 |
return false; |
} |
screen.fb_addr = (unsigned char *) addr; |
screen.fbaddress = (unsigned char *) addr; |
screen.xres = xres; |
screen.yres = yres; |
screen.scanline = scan; |
screen.invert_colors = invert_colors; |
screen.glyphscanline = FONT_WIDTH * screen.pixelbytes; |
screen.glyphbytes = screen.glyphscanline * FONT_SCANLINES; |
/* Create first viewport */ |
vport_create(0, 0, xres, yres); |
viewport_create(0, 0, xres, yres); |
return true; |
} |
/** Draw a glyph, takes advantage of alignment. |
* |
* This version can only be used if the following conditions are met: |
* |
* - word size is divisible by pixelbytes |
* - cell scanline size is divisible by word size |
* - cell scanlines are word-aligned |
* |
* It makes use of the pre-rendered mask to process (possibly) several |
* pixels at once (word size / pixelbytes pixels at a time are processed) |
* making it very fast. Most notably this version is not applicable at 24 bits |
* per pixel. |
* |
* @param x x coordinate of top-left corner on screen. |
* @param y y coordinate of top-left corner on screen. |
* @param cursor Draw glyph with cursor |
* @param glyphs Pointer to font bitmap. |
* @param glyph Code of the glyph to draw. |
* @param fg_color Foreground color. |
* @param bg_color Backgroudn color. |
*/ |
static void draw_glyph_aligned(unsigned int x, unsigned int y, bool cursor, |
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) |
/** Hide cursor if it is shown */ |
static void |
cursor_hide(viewport_t *vport) |
{ |
unsigned int i, yd; |
unsigned long fg_buf, bg_buf; |
unsigned long *maskp, *dp; |
unsigned long mask; |
unsigned int ww, d_add; |
/* |
* Prepare a pair of words, one filled with foreground-color |
* pattern and the other filled with background-color pattern. |
*/ |
for (i = 0; i < sizeof(unsigned long) / screen.pixelbytes; i++) { |
screen.rgb_conv(&((uint8_t *)&fg_buf)[i * screen.pixelbytes], |
fg_color); |
screen.rgb_conv(&((uint8_t *)&bg_buf)[i * screen.pixelbytes], |
bg_color); |
if (vport->cursor_active && vport->cursor_shown) { |
invert_char(vport, vport->cur_row, vport->cur_col); |
vport->cursor_shown = 0; |
} |
/* Pointer to the current position in the mask. */ |
maskp = (unsigned long *) &glyphs[GLYPH_POS(glyph, 0, cursor)]; |
/* Pointer to the current position on the screen. */ |
dp = (unsigned long *) &screen.fb_addr[FB_POS(x, y)]; |
/* Width of the character cell in words. */ |
ww = FONT_WIDTH * screen.pixelbytes / sizeof(unsigned long); |
/* Offset to add when moving to another screen scanline. */ |
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
/* |
* Now process the cell scanline, combining foreground |
* and background color patters using the pre-rendered mask. |
*/ |
for (i = 0; i < ww; i++) { |
mask = *maskp++; |
*dp++ = (fg_buf & mask) | (bg_buf & ~mask); |
} |
/* Move to the beginning of the next scanline of the cell. */ |
dp = (unsigned long *) ((uint8_t *) dp + d_add); |
} |
} |
/** Draw a glyph, fallback version. |
* |
* This version does not make use of the pre-rendered mask, it uses |
* the font bitmap directly. It works always, but it is slower. |
* |
* @param x x coordinate of top-left corner on screen. |
* @param y y coordinate of top-left corner on screen. |
* @param cursor Draw glyph with cursor |
* @param glyphs Pointer to font bitmap. |
* @param glyph Code of the glyph to draw. |
* @param fg_color Foreground color. |
* @param bg_color Backgroudn color. |
*/ |
void draw_glyph_fallback(unsigned int x, unsigned int y, bool cursor, |
uint8_t *glyphs, uint8_t glyph, uint32_t fg_color, uint32_t bg_color) |
/** Show cursor if cursor showing is enabled */ |
static void |
cursor_print(viewport_t *vport) |
{ |
unsigned int i, j, yd; |
uint8_t fg_buf[4], bg_buf[4]; |
uint8_t *dp, *sp; |
unsigned int d_add; |
uint8_t b; |
/* Pre-render 1x the foreground and background color pixels. */ |
if (cursor) { |
screen.rgb_conv(fg_buf, bg_color); |
screen.rgb_conv(bg_buf, fg_color); |
} else { |
screen.rgb_conv(fg_buf, fg_color); |
screen.rgb_conv(bg_buf, bg_color); |
} |
/* Pointer to the current position on the screen. */ |
dp = (uint8_t *) &screen.fb_addr[FB_POS(x, y)]; |
/* Offset to add when moving to another screen scanline. */ |
d_add = screen.scanline - FONT_WIDTH * screen.pixelbytes; |
for (yd = 0; yd < FONT_SCANLINES; yd++) { |
/* Byte containing bits of the glyph scanline. */ |
b = fb_font[glyph * FONT_SCANLINES + yd]; |
for (i = 0; i < FONT_WIDTH; i++) { |
/* Choose color based on the current bit. */ |
sp = (b & 0x80) ? fg_buf : bg_buf; |
/* Copy the pixel. */ |
for (j = 0; j < screen.pixelbytes; j++) { |
*dp++ = *sp++; |
} |
/* Move to the next bit. */ |
b = b << 1; |
} |
/* Move to the beginning of the next scanline of the cell. */ |
dp += d_add; |
} |
} |
/** Draw glyph at specified position in viewport. |
* |
* @param vport Viewport identification |
* @param cursor Draw glyph with cursor |
* @param col Screen position relative to viewport |
* @param row Screen position relative to viewport |
* |
*/ |
static void draw_vp_glyph(viewport_t *vport, bool cursor, unsigned int col, |
unsigned int row) |
{ |
unsigned int x = vport->x + COL2X(col); |
unsigned int y = vport->y + ROW2Y(row); |
uint8_t glyph; |
uint32_t fg_color; |
uint32_t bg_color; |
glyph = vport->backbuf[BB_POS(vport, col, row)].glyph; |
fg_color = vport->backbuf[BB_POS(vport, col, row)].fg_color; |
bg_color = vport->backbuf[BB_POS(vport, col, row)].bg_color; |
(*vport->dglyph)(x, y, cursor, vport->glyphs, glyph, |
fg_color, bg_color); |
} |
/** Hide cursor if it is shown |
* |
*/ |
static void cursor_hide(viewport_t *vport) |
{ |
if ((vport->cursor_active) && (vport->cursor_shown)) { |
draw_vp_glyph(vport, false, vport->cur_col, vport->cur_row); |
vport->cursor_shown = false; |
} |
} |
/** Show cursor if cursor showing is enabled |
* |
*/ |
static void cursor_show(viewport_t *vport) |
{ |
/* Do not check for cursor_shown */ |
if (vport->cursor_active) { |
draw_vp_glyph(vport, true, vport->cur_col, vport->cur_row); |
vport->cursor_shown = true; |
invert_char(vport, vport->cur_row, vport->cur_col); |
vport->cursor_shown = 1; |
} |
} |
/** Invert cursor, if it is enabled |
* |
*/ |
static void cursor_blink(viewport_t *vport) |
/** Invert cursor, if it is enabled */ |
static void |
cursor_blink(viewport_t *vport) |
{ |
if (vport->cursor_shown) |
cursor_hide(vport); |
else |
cursor_show(vport); |
cursor_print(vport); |
} |
/** Draw character at given position relative to viewport |
* |
* @param vport Viewport identification |
* @param c Character to draw |
* @param col Screen position relative to viewport |
* @param row Screen position relative to viewport |
* |
/** Draw character at given position relative to viewport |
* |
* @param vport Viewport identification |
* @param c Character to print |
* @param row Screen position relative to viewport |
* @param col Screen position relative to viewport |
* @param transparent If false, print background color with character |
*/ |
static void draw_char(viewport_t *vport, uint8_t c, unsigned int col, unsigned int row) |
static void |
draw_char(viewport_t *vport, char c, unsigned int row, unsigned int col, |
style_t style, int transparent) |
{ |
bb_cell_t *bbp; |
/* Optimize - do not hide cursor if we are going to overwrite it */ |
if (vport->cursor_active && vport->cursor_shown && |
(vport->cur_col != col || vport->cur_row != row)) |
invert_char(vport, vport->cur_row, vport->cur_col); |
draw_glyph(vport, c, col * COL_WIDTH, row * FONT_SCANLINES, style, |
transparent); |
/* Do not hide cursor if we are going to overwrite it */ |
if ((vport->cursor_active) && (vport->cursor_shown) && |
((vport->cur_col != col) || (vport->cur_row != row))) |
cursor_hide(vport); |
bbp = &vport->backbuf[BB_POS(vport, col, row)]; |
bbp->glyph = c; |
bbp->fg_color = vport->attr.fg_color; |
bbp->bg_color = vport->attr.bg_color; |
draw_vp_glyph(vport, false, col, row); |
vport->cur_col = col; |
vport->cur_row = row; |
vport->cur_col++; |
if (vport->cur_col >= vport->cols) { |
vport->cur_col = 0; |
862,91 → 637,65 |
if (vport->cur_row >= vport->rows) |
vport->cur_row--; |
} |
cursor_show(vport); |
cursor_print(vport); |
} |
/** Draw text data to viewport |
* |
* @param vport Viewport id |
* @param data Text data fitting exactly into viewport |
* |
* @param data Text data fitting exactly into viewport |
*/ |
static void draw_text_data(viewport_t *vport, keyfield_t *data) |
static void |
draw_text_data(viewport_t *vport, keyfield_t *data) |
{ |
unsigned int i; |
bb_cell_t *bbp; |
attrs_t *a; |
attr_rgb_t rgb; |
int i; |
int col,row; |
clear_port(vport); |
for (i = 0; i < vport->cols * vport->rows; i++) { |
unsigned int col = i % vport->cols; |
unsigned int row = i / vport->cols; |
bbp = &vport->backbuf[BB_POS(vport, col, row)]; |
uint8_t glyph = bbp->glyph; |
a = &data[i].attrs; |
rgb_from_attr(&rgb, a); |
bbp->glyph = data[i].character; |
bbp->fg_color = rgb.fg_color; |
bbp->bg_color = rgb.bg_color; |
draw_vp_glyph(vport, false, col, row); |
if (data[i].character == ' ' && style_same(data[i].style, |
vport->style)) |
continue; |
col = i % vport->cols; |
row = i / vport->cols; |
draw_glyph(vport, data[i].character, col * COL_WIDTH, row * |
FONT_SCANLINES, data[i].style, style_same(data[i].style, |
vport->style)); |
} |
cursor_show(vport); |
cursor_print(vport); |
} |
static void putpixel_pixmap(void *data, unsigned int x, unsigned int y, uint32_t color) |
/** Return first free pixmap */ |
static int |
find_free_pixmap(void) |
{ |
int pm = *((int *) data); |
pixmap_t *pmap = &pixmaps[pm]; |
unsigned int pos = (y * pmap->width + x) * screen.pixelbytes; |
int i; |
screen.rgb_conv(&pmap->data[pos], color); |
for (i = 0;i < MAX_PIXMAPS;i++) |
if (!pixmaps[i].data) |
return i; |
return -1; |
} |
static void putpixel(void *data, unsigned int x, unsigned int y, uint32_t color) |
static void |
putpixel_pixmap(int pm, unsigned int x, unsigned int y, int color) |
{ |
viewport_t *vport = (viewport_t *) data; |
unsigned int dx = vport->x + x; |
unsigned int dy = vport->y + y; |
screen.rgb_conv(&screen.fb_addr[FB_POS(dx, dy)], color); |
} |
pixmap_t *pmap = &pixmaps[pm]; |
int pos = (y * pmap->width + x) * screen.pixelbytes; |
/** Return first free pixmap |
* |
*/ |
static int find_free_pixmap(void) |
{ |
unsigned int i; |
for (i = 0; i < MAX_PIXMAPS; i++) |
if (!pixmaps[i].data) |
return i; |
return -1; |
(*screen.rgb2scr)(&pmap->data[pos],COLOR(color)); |
} |
/** Create a new pixmap and return appropriate ID |
* |
*/ |
static int shm2pixmap(unsigned char *shm, size_t size) |
/** Create a new pixmap and return appropriate ID */ |
static int |
shm2pixmap(unsigned char *shm, size_t size) |
{ |
int pm; |
pixmap_t *pmap; |
pm = find_free_pixmap(); |
if (pm == -1) |
return ELIMIT; |
pmap = &pixmaps[pm]; |
if (ppm_get_data(shm, size, &pmap->width, &pmap->height)) |
955,19 → 704,19 |
pmap->data = malloc(pmap->width * pmap->height * screen.pixelbytes); |
if (!pmap->data) |
return ENOMEM; |
ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, putpixel_pixmap, (void *) &pm); |
ppm_draw(shm, size, 0, 0, pmap->width, pmap->height, |
(putpixel_cb_t)putpixel_pixmap, (void *)pm); |
return pm; |
} |
/** Handle shared memory communication calls |
* |
* Protocol for drawing pixmaps: |
* - FB_PREPARE_SHM(client shm identification) |
* - IPC_M_AS_AREA_SEND |
* - FB_DRAW_PPM(startx, starty) |
* - FB_DRAW_PPM(startx,starty) |
* - FB_DROP_SHM |
* |
* Protocol for text drawing |
975,30 → 724,28 |
* - FB_DRAW_TEXT_DATA |
* |
* @param callid Callid of the current call |
* @param call Current call data |
* @param vp Active viewport |
* @param call Current call data |
* @param vp Active viewport |
* @return 0 if the call was not handled byt this function, 1 otherwise |
* |
* @return false if the call was not handled byt this function, true otherwise |
* |
* Note: this function is not threads safe, you would have |
* note: this function is not threads safe, you would have |
* to redefine static variables with __thread |
* |
*/ |
static bool shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
static int |
shm_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
{ |
static keyfield_t *interbuffer = NULL; |
static size_t intersize = 0; |
static unsigned char *shm = NULL; |
static ipcarg_t shm_id = 0; |
static size_t shm_size; |
bool handled = true; |
int retval = EOK; |
int handled = 1; |
int retval = 0; |
viewport_t *vport = &viewports[vp]; |
unsigned int x; |
unsigned int y; |
unsigned int x, y; |
switch (IPC_GET_METHOD(*call)) { |
case IPC_M_SHARE_OUT: |
/* We accept one area for data interchange */ |
1005,20 → 752,19 |
if (IPC_GET_ARG1(*call) == shm_id) { |
void *dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
shm_size = IPC_GET_ARG2(*call); |
if (!ipc_answer_1(callid, EOK, (sysarg_t) dest)) |
if (!ipc_answer_1(callid, EOK, (sysarg_t) dest)) |
shm = dest; |
else |
shm_id = 0; |
if (shm[0] != 'P') |
return false; |
return true; |
while (1) |
; |
return 1; |
} else { |
intersize = IPC_GET_ARG2(*call); |
receive_comm_area(callid, call, (void *) &interbuffer); |
} |
return true; |
return 1; |
case FB_PREPARE_SHM: |
if (shm_id) |
retval = EBUSY; |
1033,7 → 779,7 |
} |
shm_id = 0; |
break; |
case FB_SHM2PIXMAP: |
if (!shm) { |
retval = EINVAL; |
1048,14 → 794,14 |
} |
x = IPC_GET_ARG1(*call); |
y = IPC_GET_ARG2(*call); |
if ((x > vport->width) || (y > vport->height)) { |
if (x > vport->width || y > vport->height) { |
retval = EINVAL; |
break; |
} |
ppm_draw(shm, shm_size, IPC_GET_ARG1(*call), |
IPC_GET_ARG2(*call), vport->width - x, vport->height - y, putpixel, (void *) vport); |
IPC_GET_ARG2(*call), vport->width - x, vport->height - y, |
(putpixel_cb_t)putpixel, vport); |
break; |
case FB_DRAW_TEXT_DATA: |
if (!interbuffer) { |
1062,7 → 808,8 |
retval = EINVAL; |
break; |
} |
if (intersize < vport->cols * vport->rows * sizeof(*interbuffer)) { |
if (intersize < vport->cols * vport->rows * |
sizeof(*interbuffer)) { |
retval = EINVAL; |
break; |
} |
1069,7 → 816,7 |
draw_text_data(vport, interbuffer); |
break; |
default: |
handled = false; |
handled = 0; |
} |
if (handled) |
1077,39 → 824,41 |
return handled; |
} |
static void |
copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap) |
{ |
int y; |
int tmp, srcrowsize; |
int realwidth, realheight, realrowsize; |
int width = vport->width; |
int height = vport->height; |
static void copy_vp_to_pixmap(viewport_t *vport, pixmap_t *pmap) |
{ |
unsigned int width = vport->width; |
unsigned int height = vport->height; |
if (width + vport->x > screen.xres) |
width = screen.xres - vport->x; |
if (height + vport->y > screen.yres) |
height = screen.yres - vport->y; |
unsigned int realwidth = pmap->width <= width ? pmap->width : width; |
unsigned int realheight = pmap->height <= height ? pmap->height : height; |
realwidth = pmap->width <= width ? pmap->width : width; |
realheight = pmap->height <= height ? pmap->height : height; |
srcrowsize = vport->width * screen.pixelbytes; |
realrowsize = realwidth * screen.pixelbytes; |
unsigned int srcrowsize = vport->width * screen.pixelbytes; |
unsigned int realrowsize = realwidth * screen.pixelbytes; |
unsigned int y; |
for (y = 0; y < realheight; y++) { |
unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; |
memcpy(pmap->data + srcrowsize * y, screen.fb_addr + tmp, realrowsize); |
tmp = (vport->y + y) * screen.scanline + |
vport->x * screen.pixelbytes; |
memcpy(pmap->data + srcrowsize * y, screen.fbaddress + tmp, |
realrowsize); |
} |
} |
/** Save viewport to pixmap |
* |
*/ |
static int save_vp_to_pixmap(viewport_t *vport) |
/** Save viewport to pixmap */ |
static int |
save_vp_to_pixmap(viewport_t *vport) |
{ |
int pm; |
pixmap_t *pmap; |
pm = find_free_pixmap(); |
if (pm == -1) |
return ELIMIT; |
1118,60 → 867,58 |
pmap->data = malloc(screen.pixelbytes * vport->width * vport->height); |
if (!pmap->data) |
return ENOMEM; |
pmap->width = vport->width; |
pmap->height = vport->height; |
copy_vp_to_pixmap(vport, pmap); |
return pm; |
} |
/** Draw pixmap on screen |
* |
* @param vp Viewport to draw on |
* @param pm Pixmap identifier |
* |
*/ |
static int draw_pixmap(int vp, int pm) |
{ |
pixmap_t *pmap = &pixmaps[pm]; |
viewport_t *vport = &viewports[vp]; |
unsigned int width = vport->width; |
unsigned int height = vport->height; |
int y; |
int tmp, srcrowsize; |
int realwidth, realheight, realrowsize; |
int width = vport->width; |
int height = vport->height; |
if (width + vport->x > screen.xres) |
width = screen.xres - vport->x; |
if (height + vport->y > screen.yres) |
height = screen.yres - vport->y; |
if (!pmap->data) |
return EINVAL; |
unsigned int realwidth = pmap->width <= width ? pmap->width : width; |
unsigned int realheight = pmap->height <= height ? pmap->height : height; |
unsigned int srcrowsize = vport->width * screen.pixelbytes; |
unsigned int realrowsize = realwidth * screen.pixelbytes; |
unsigned int y; |
realwidth = pmap->width <= width ? pmap->width : width; |
realheight = pmap->height <= height ? pmap->height : height; |
srcrowsize = vport->width * screen.pixelbytes; |
realrowsize = realwidth * screen.pixelbytes; |
for (y = 0; y < realheight; y++) { |
unsigned int tmp = (vport->y + y) * screen.scanline + vport->x * screen.pixelbytes; |
memcpy(screen.fb_addr + tmp, pmap->data + y * srcrowsize, realrowsize); |
tmp = (vport->y + y) * screen.scanline + |
vport->x * screen.pixelbytes; |
memcpy(screen.fbaddress + tmp, pmap->data + y * srcrowsize, |
realrowsize); |
} |
return EOK; |
return 0; |
} |
/** Tick animation one step forward |
* |
*/ |
static void anims_tick(void) |
/** Tick animation one step forward */ |
static void |
anims_tick(void) |
{ |
unsigned int i; |
int i; |
static int counts = 0; |
/* Limit redrawing */ |
1180,36 → 927,37 |
return; |
for (i = 0; i < MAX_ANIMATIONS; i++) { |
if ((!animations[i].animlen) || (!animations[i].initialized) || |
(!animations[i].enabled)) |
if (!animations[i].animlen || !animations[i].initialized || |
!animations[i].enabled) |
continue; |
draw_pixmap(animations[i].vp, animations[i].pixmaps[animations[i].pos]); |
animations[i].pos = (animations[i].pos + 1) % animations[i].animlen; |
draw_pixmap(animations[i].vp, |
animations[i].pixmaps[animations[i].pos]); |
animations[i].pos = (animations[i].pos + 1) % |
animations[i].animlen; |
} |
} |
static unsigned int pointer_x; |
static unsigned int pointer_y; |
static bool pointer_shown, pointer_enabled; |
static int pointer_x, pointer_y; |
static int pointer_shown, pointer_enabled; |
static int pointer_vport = -1; |
static int pointer_pixmap = -1; |
static void mouse_show(void) |
static void |
mouse_show(void) |
{ |
int i, j; |
int visibility; |
int color; |
int bytepos; |
if ((pointer_shown) || (!pointer_enabled)) |
if (pointer_shown || !pointer_enabled) |
return; |
/* Save image under the pointer. */ |
/* Save image under the cursor */ |
if (pointer_vport == -1) { |
pointer_vport = vport_create(pointer_x, pointer_y, pointer_width, pointer_height); |
pointer_vport = viewport_create(pointer_x, pointer_y, |
pointer_width, pointer_height); |
if (pointer_vport < 0) |
return; |
} else { |
1216,13 → 964,14 |
viewports[pointer_vport].x = pointer_x; |
viewports[pointer_vport].y = pointer_y; |
} |
if (pointer_pixmap == -1) |
pointer_pixmap = save_vp_to_pixmap(&viewports[pointer_vport]); |
else |
copy_vp_to_pixmap(&viewports[pointer_vport], &pixmaps[pointer_pixmap]); |
/* Draw mouse pointer. */ |
copy_vp_to_pixmap(&viewports[pointer_vport], |
&pixmaps[pointer_pixmap]); |
/* Draw cursor */ |
for (i = 0; i < pointer_height; i++) |
for (j = 0; j < pointer_width; j++) { |
bytepos = i * ((pointer_width - 1) / 8 + 1) + j / 8; |
1240,10 → 989,10 |
pointer_shown = 1; |
} |
static void mouse_hide(void) |
static void |
mouse_hide(void) |
{ |
/* Restore image under the pointer. */ |
/* Restore image under the cursor */ |
if (pointer_shown) { |
draw_pixmap(pointer_vport, pointer_pixmap); |
pointer_shown = 0; |
1250,8 → 999,8 |
} |
} |
static void mouse_move(unsigned int x, unsigned int y) |
static void |
mouse_move(unsigned int x, unsigned int y) |
{ |
mouse_hide(); |
pointer_x = x; |
1259,14 → 1008,14 |
mouse_show(); |
} |
static int anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
static int |
anim_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
{ |
bool handled = true; |
int retval = EOK; |
int i, nvp; |
int handled = 1; |
int retval = 0; |
int i,nvp; |
int newval; |
switch (IPC_GET_METHOD(*call)) { |
case FB_ANIM_CREATE: |
nvp = IPC_GET_ARG1(*call); |
1356,16 → 1105,14 |
return handled; |
} |
/** Handler for messages concerning pixmap handling */ |
static int |
pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
{ |
int handled = 1; |
int retval = 0; |
int i,nvp; |
/** Handler for messages concerning pixmap handling |
* |
*/ |
static int pixmap_handle(ipc_callid_t callid, ipc_call_t *call, int vp) |
{ |
bool handled = true; |
int retval = EOK; |
int i, nvp; |
switch (IPC_GET_METHOD(*call)) { |
case FB_VP_DRAW_PIXMAP: |
nvp = IPC_GET_ARG1(*call); |
1403,7 → 1150,7 |
default: |
handled = 0; |
} |
if (handled) |
ipc_answer_0(callid, retval); |
return handled; |
1410,99 → 1157,35 |
} |
static int rgb_from_style(attr_rgb_t *rgb, int style) |
{ |
switch (style) { |
case STYLE_NORMAL: |
rgb->fg_color = color_table[COLOR_BLACK]; |
rgb->bg_color = color_table[COLOR_WHITE]; |
break; |
case STYLE_EMPHASIS: |
rgb->fg_color = color_table[COLOR_RED]; |
rgb->bg_color = color_table[COLOR_WHITE]; |
break; |
default: |
return EINVAL; |
} |
return EOK; |
} |
static int rgb_from_idx(attr_rgb_t *rgb, ipcarg_t fg_color, |
ipcarg_t bg_color, ipcarg_t flags) |
{ |
fg_color = (fg_color & 7) | ((flags & CATTR_BRIGHT) ? 8 : 0); |
bg_color = (bg_color & 7) | ((flags & CATTR_BRIGHT) ? 8 : 0); |
rgb->fg_color = color_table[fg_color]; |
rgb->bg_color = color_table[bg_color]; |
return EOK; |
} |
static int rgb_from_attr(attr_rgb_t *rgb, const attrs_t *a) |
{ |
int rc; |
switch (a->t) { |
case at_style: |
rc = rgb_from_style(rgb, a->a.s.style); |
break; |
case at_idx: |
rc = rgb_from_idx(rgb, a->a.i.fg_color, |
a->a.i.bg_color, a->a.i.flags); |
break; |
case at_rgb: |
*rgb = a->a.r; |
rc = EOK; |
break; |
} |
return rc; |
} |
static int fb_set_style(viewport_t *vport, ipcarg_t style) |
{ |
return rgb_from_style(&vport->attr, (int) style); |
} |
static int fb_set_color(viewport_t *vport, ipcarg_t fg_color, |
ipcarg_t bg_color, ipcarg_t flags) |
{ |
return rgb_from_idx(&vport->attr, fg_color, bg_color, flags); |
} |
/** Function for handling connections to FB |
* |
*/ |
static void fb_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
static void |
fb_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
unsigned int vp = 0; |
viewport_t *vport = &viewports[vp]; |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
int i; |
unsigned int row,col; |
char c; |
int vp = 0; |
viewport_t *vport = &viewports[0]; |
if (client_connected) { |
ipc_answer_0(iid, ELIMIT); |
return; |
} |
/* Accept connection */ |
client_connected = true; |
ipc_answer_0(iid, EOK); |
while (true) { |
ipc_callid_t callid; |
ipc_call_t call; |
int retval; |
unsigned int i; |
int scroll; |
uint8_t glyph; |
unsigned int row, col; |
if ((vport->cursor_active) || (anims_enabled)) |
client_connected = 1; |
ipc_answer_0(iid, EOK); /* Accept connection */ |
while (1) { |
if (vport->cursor_active || anims_enabled) |
callid = async_get_call_timeout(&call, 250000); |
else |
callid = async_get_call(&call); |
mouse_hide(); |
if (!callid) { |
cursor_blink(vport); |
1510,89 → 1193,105 |
mouse_show(); |
continue; |
} |
if (shm_handle(callid, &call, vp)) |
continue; |
if (pixmap_handle(callid, &call, vp)) |
continue; |
if (anim_handle(callid, &call, vp)) |
continue; |
switch (IPC_GET_METHOD(call)) { |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
client_connected = false; |
/* Cleanup other viewports */ |
client_connected = 0; |
/* cleanup other viewports */ |
for (i = 1; i < MAX_VIEWPORTS; i++) |
vport->initialized = false; |
/* Exit thread */ |
return; |
vport->initialized = 0; |
return; /* Exit thread */ |
case FB_PUTCHAR: |
glyph = IPC_GET_ARG1(call); |
case FB_TRANS_PUTCHAR: |
c = IPC_GET_ARG1(call); |
row = IPC_GET_ARG2(call); |
col = IPC_GET_ARG3(call); |
if ((col >= vport->cols) || (row >= vport->rows)) { |
if (row >= vport->rows || col >= vport->cols) { |
retval = EINVAL; |
break; |
} |
ipc_answer_0(callid, EOK); |
draw_char(vport, glyph, col, row); |
/* Message already answered */ |
continue; |
draw_char(vport, c, row, col, vport->style, |
IPC_GET_METHOD(call) == FB_TRANS_PUTCHAR); |
continue; /* msg already answered */ |
case FB_CLEAR: |
vport_clear(vport); |
cursor_show(vport); |
retval = EOK; |
clear_port(vport); |
cursor_print(vport); |
retval = 0; |
break; |
case FB_CURSOR_GOTO: |
case FB_CURSOR_GOTO: |
row = IPC_GET_ARG1(call); |
col = IPC_GET_ARG2(call); |
if ((col >= vport->cols) || (row >= vport->rows)) { |
if (row >= vport->rows || col >= vport->cols) { |
retval = EINVAL; |
break; |
} |
retval = EOK; |
retval = 0; |
cursor_hide(vport); |
vport->cur_col = col; |
vport->cur_row = row; |
cursor_show(vport); |
break; |
cursor_print(vport); |
break; |
case FB_CURSOR_VISIBILITY: |
cursor_hide(vport); |
vport->cursor_active = IPC_GET_ARG1(call); |
cursor_show(vport); |
retval = EOK; |
cursor_print(vport); |
retval = 0; |
break; |
case FB_GET_CSIZE: |
ipc_answer_2(callid, EOK, vport->rows, vport->cols); |
continue; |
case FB_SCROLL: |
scroll = IPC_GET_ARG1(call); |
if ((scroll > (int) vport->rows) || (scroll < (-(int) vport->rows))) { |
i = IPC_GET_ARG1(call); |
if (i > vport->rows || i < (- (int)vport->rows)) { |
retval = EINVAL; |
break; |
} |
cursor_hide(vport); |
vport_scroll(vport, scroll); |
cursor_show(vport); |
retval = EOK; |
scroll_port(vport, i*FONT_SCANLINES); |
cursor_print(vport); |
retval = 0; |
break; |
case FB_VIEWPORT_DB: |
/* Enable double buffering */ |
i = IPC_GET_ARG1(call); |
if (i == -1) |
i = vp; |
if (i < 0 || i >= MAX_VIEWPORTS) { |
retval = EINVAL; |
break; |
} |
if (!viewports[i].initialized ) { |
retval = EADDRNOTAVAIL; |
break; |
} |
viewports[i].dboffset = 0; |
if (IPC_GET_ARG2(call) == 1 && !viewports[i].dbdata) |
viewports[i].dbdata = |
malloc(screen.pixelbytes * |
viewports[i].width * viewports[i].height); |
else if (IPC_GET_ARG2(call) == 0 && |
viewports[i].dbdata) { |
free(viewports[i].dbdata); |
viewports[i].dbdata = NULL; |
} |
retval = 0; |
break; |
case FB_VIEWPORT_SWITCH: |
i = IPC_GET_ARG1(call); |
if (i >= MAX_VIEWPORTS) { |
if (i < 0 || i >= MAX_VIEWPORTS) { |
retval = EINVAL; |
break; |
} |
if (!viewports[i].initialized) { |
if (! viewports[i].initialized ) { |
retval = EADDRNOTAVAIL; |
break; |
} |
1599,11 → 1298,11 |
cursor_hide(vport); |
vp = i; |
vport = &viewports[vp]; |
cursor_show(vport); |
retval = EOK; |
cursor_print(vport); |
retval = 0; |
break; |
case FB_VIEWPORT_CREATE: |
retval = vport_create(IPC_GET_ARG1(call) >> 16, |
retval = viewport_create(IPC_GET_ARG1(call) >> 16, |
IPC_GET_ARG1(call) & 0xffff, |
IPC_GET_ARG2(call) >> 16, |
IPC_GET_ARG2(call) & 0xffff); |
1610,42 → 1309,33 |
break; |
case FB_VIEWPORT_DELETE: |
i = IPC_GET_ARG1(call); |
if (i >= MAX_VIEWPORTS) { |
if (i < 0 || i >= MAX_VIEWPORTS) { |
retval = EINVAL; |
break; |
} |
if (!viewports[i].initialized) { |
if (! viewports[i].initialized ) { |
retval = EADDRNOTAVAIL; |
break; |
} |
viewports[i].initialized = false; |
if (viewports[i].glyphs) |
free(viewports[i].glyphs); |
if (viewports[i].bgpixel) |
free(viewports[i].bgpixel); |
if (viewports[i].backbuf) |
free(viewports[i].backbuf); |
retval = EOK; |
viewports[i].initialized = 0; |
if (viewports[i].dbdata) { |
free(viewports[i].dbdata); |
viewports[i].dbdata = NULL; |
} |
retval = 0; |
break; |
case FB_SET_STYLE: |
retval = fb_set_style(vport, IPC_GET_ARG1(call)); |
vport->style.fg_color = IPC_GET_ARG1(call); |
vport->style.bg_color = IPC_GET_ARG2(call); |
retval = 0; |
break; |
case FB_SET_COLOR: |
retval = fb_set_color(vport, IPC_GET_ARG1(call), |
IPC_GET_ARG2(call), IPC_GET_ARG3(call)); |
break; |
case FB_SET_RGB_COLOR: |
vport->attr.fg_color = IPC_GET_ARG1(call); |
vport->attr.bg_color = IPC_GET_ARG2(call); |
retval = EOK; |
break; |
case FB_GET_RESOLUTION: |
ipc_answer_2(callid, EOK, screen.xres, screen.yres); |
continue; |
case FB_POINTER_MOVE: |
pointer_enabled = true; |
pointer_enabled = 1; |
mouse_move(IPC_GET_ARG1(call), IPC_GET_ARG2(call)); |
retval = EOK; |
retval = 0; |
break; |
default: |
retval = ENOENT; |
1654,33 → 1344,41 |
} |
} |
/** Initialization of framebuffer |
* |
*/ |
int fb_init(void) |
/** Initialization of framebuffer */ |
int |
fb_init(void) |
{ |
void *fb_ph_addr; |
unsigned int fb_width; |
unsigned int fb_height; |
unsigned int fb_scanline; |
unsigned int fb_visual; |
bool fb_invert_colors; |
void *fb_addr; |
size_t asz; |
async_set_client_connection(fb_client_connection); |
fb_ph_addr = (void *) sysinfo_value("fb.address.physical"); |
fb_width = sysinfo_value("fb.width"); |
fb_height = sysinfo_value("fb.height"); |
fb_scanline = sysinfo_value("fb.scanline"); |
fb_visual = sysinfo_value("fb.visual"); |
fb_invert_colors = sysinfo_value("fb.invert-colors"); |
asz = fb_scanline * fb_height; |
fb_addr = as_get_mappable_page(asz); |
void *fb_ph_addr = (void *) sysinfo_value("fb.address.physical"); |
unsigned int fb_offset = sysinfo_value("fb.offset"); |
unsigned int fb_width = sysinfo_value("fb.width"); |
unsigned int fb_height = sysinfo_value("fb.height"); |
unsigned int fb_scanline = sysinfo_value("fb.scanline"); |
unsigned int fb_visual = sysinfo_value("fb.visual"); |
unsigned int fbsize = fb_scanline * fb_height; |
void *fb_addr = as_get_mappable_page(fbsize); |
if (physmem_map(fb_ph_addr + fb_offset, fb_addr, |
ALIGN_UP(fbsize, PAGE_SIZE) >> PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0) |
return -1; |
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual)) |
physmem_map(fb_ph_addr, fb_addr, ALIGN_UP(asz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
if (screen_init(fb_addr, fb_width, fb_height, fb_scanline, fb_visual, |
fb_invert_colors)) |
return 0; |
return -1; |
} |
/** |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/fb/ega.c |
---|
49,9 → 49,6 |
#include <ipc/ns.h> |
#include <ipc/services.h> |
#include <libarch/ddi.h> |
#include <console/style.h> |
#include <console/color.h> |
#include <sys/types.h> |
#include "ega.h" |
#include "../console/screenbuffer.h" |
64,14 → 61,13 |
saved_screen saved_screens[MAX_SAVED_SCREENS]; |
#define EGA_IO_BASE ((ioport8_t *) 0x3d4) |
#define EGA_IO_ADDRESS 0x3d4 |
#define EGA_IO_SIZE 2 |
int ega_normal_color = 0x0f; |
int ega_inverted_color = 0xf0; |
#define NORMAL_COLOR 0x0f |
#define INVERTED_COLOR 0xf0 |
#define NORMAL_COLOR ega_normal_color |
#define INVERTED_COLOR ega_inverted_color |
#define EGA_STYLE(fg,bg) ((fg) > (bg) ? NORMAL_COLOR : INVERTED_COLOR) |
/* Allow only 1 connection */ |
static int client_connected = 0; |
80,10 → 76,8 |
static unsigned int scr_height; |
static char *scr_addr; |
static unsigned int style; |
static unsigned int style = NORMAL_COLOR; |
static unsigned attr_to_ega_style(const attrs_t *a); |
static void clrscr(void) |
{ |
int i; |
100,10 → 94,10 |
ega_cursor = col + scr_width * row; |
pio_write_8(EGA_IO_BASE, 0xe); |
pio_write_8(EGA_IO_BASE + 1, (ega_cursor >> 8) & 0xff); |
pio_write_8(EGA_IO_BASE, 0xf); |
pio_write_8(EGA_IO_BASE + 1, ega_cursor & 0xff); |
outb(EGA_IO_ADDRESS, 0xe); |
outb(EGA_IO_ADDRESS + 1, (ega_cursor >> 8) & 0xff); |
outb(EGA_IO_ADDRESS, 0xf); |
outb(EGA_IO_ADDRESS + 1, ega_cursor & 0xff); |
} |
static void cursor_disable(void) |
110,10 → 104,10 |
{ |
uint8_t stat; |
pio_write_8(EGA_IO_BASE, 0xa); |
stat = pio_read_8(EGA_IO_BASE + 1); |
pio_write_8(EGA_IO_BASE, 0xa); |
pio_write_8(EGA_IO_BASE + 1, stat | (1 << 5)); |
outb(EGA_IO_ADDRESS, 0xa); |
stat=inb(EGA_IO_ADDRESS + 1); |
outb(EGA_IO_ADDRESS, 0xa); |
outb(EGA_IO_ADDRESS + 1, stat | (1 << 5)); |
} |
static void cursor_enable(void) |
120,10 → 114,10 |
{ |
uint8_t stat; |
pio_write_8(EGA_IO_BASE, 0xa); |
stat = pio_read_8(EGA_IO_BASE + 1); |
pio_write_8(EGA_IO_BASE, 0xa); |
pio_write_8(EGA_IO_BASE + 1, stat & (~(1 << 5))); |
outb(EGA_IO_ADDRESS, 0xa); |
stat=inb(EGA_IO_ADDRESS + 1); |
outb(EGA_IO_ADDRESS, 0xa); |
outb(EGA_IO_ADDRESS + 1, stat & (~(1 << 5))); |
} |
static void scroll(int rows) |
130,13 → 124,13 |
{ |
int i; |
if (rows > 0) { |
memmove(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, |
memcpy(scr_addr, ((char *) scr_addr) + rows * scr_width * 2, |
scr_width * scr_height * 2 - rows * scr_width * 2); |
for (i = 0; i < rows * scr_width; i++) |
(((short *) scr_addr) + scr_width * scr_height - rows * |
scr_width)[i] = ((style << 8) + ' '); |
} else if (rows < 0) { |
memmove(((char *)scr_addr) - rows * scr_width * 2, scr_addr, |
memcpy(((char *)scr_addr) - rows * scr_width * 2, scr_addr, |
scr_width * scr_height * 2 + rows * scr_width * 2); |
for (i = 0; i < -rows * scr_width; i++) |
((short *)scr_addr)[i] = ((style << 8 ) + ' '); |
157,7 → 151,8 |
for (i = 0; i < scr_width * scr_height; i++) { |
scr_addr[i * 2] = data[i].character; |
scr_addr[i * 2 + 1] = attr_to_ega_style(&data[i].attrs); |
scr_addr[i * 2 + 1] = EGA_STYLE(data[i].style.fg_color, |
data[i].style.bg_color); |
} |
} |
186,51 → 181,7 |
return i; |
} |
static int style_to_ega_style(int style) |
{ |
unsigned int ega_style; |
switch (style) { |
case STYLE_NORMAL: |
ega_style = INVERTED_COLOR; |
break; |
case STYLE_EMPHASIS: |
ega_style = INVERTED_COLOR | 4; |
break; |
default: |
return INVERTED_COLOR; |
} |
return ega_style; |
} |
static unsigned int color_to_ega_style(int fg_color, int bg_color, int attr) |
{ |
unsigned int style; |
style = (fg_color & 7) | ((bg_color & 7) << 4); |
if (attr & CATTR_BRIGHT) |
style = style | 0x08; |
return style; |
} |
static unsigned int rgb_to_ega_style(uint32_t fg, uint32_t bg) |
{ |
return (fg > bg) ? NORMAL_COLOR : INVERTED_COLOR; |
} |
static unsigned attr_to_ega_style(const attrs_t *a) |
{ |
switch (a->t) { |
case at_style: return style_to_ega_style(a->a.s.style); |
case at_rgb: return rgb_to_ega_style(a->a.r.fg_color, a->a.r.bg_color); |
case at_idx: return color_to_ega_style(a->a.i.fg_color, |
a->a.i.bg_color, a->a.i.flags); |
default: return INVERTED_COLOR; |
} |
} |
static void ega_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
238,8 → 189,7 |
ipc_call_t call; |
char c; |
unsigned int row, col; |
int bg_color, fg_color, attr; |
uint32_t bg_rgb, fg_rgb; |
int bgcolor,fgcolor; |
keyfield_t *interbuf = NULL; |
size_t intersize = 0; |
int i; |
315,7 → 265,7 |
retval = 0; |
break; |
case FB_CURSOR_VISIBILITY: |
if (IPC_GET_ARG1(call)) |
if(IPC_GET_ARG1(call)) |
cursor_enable(); |
else |
cursor_disable(); |
322,22 → 272,11 |
retval = 0; |
break; |
case FB_SET_STYLE: |
style = style_to_ega_style(IPC_GET_ARG1(call)); |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
style = EGA_STYLE(fgcolor, bgcolor); |
retval = 0; |
break; |
case FB_SET_COLOR: |
fg_color = IPC_GET_ARG1(call); |
bg_color = IPC_GET_ARG2(call); |
attr = IPC_GET_ARG3(call); |
style = color_to_ega_style(fg_color, bg_color, attr); |
retval = 0; |
break; |
case FB_SET_RGB_COLOR: |
fg_rgb = IPC_GET_ARG1(call); |
bg_rgb = IPC_GET_ARG2(call); |
style = rgb_to_ega_style(fg_rgb, bg_rgb); |
retval = 0; |
break; |
case FB_VP_DRAW_PIXMAP: |
i = IPC_GET_ARG2(call); |
retval = print_screen(i); |
373,22 → 312,13 |
ega_ph_addr = (void *) sysinfo_value("fb.address.physical"); |
scr_width = sysinfo_value("fb.width"); |
scr_height = sysinfo_value("fb.height"); |
iospace_enable(task_get_id(), (void *) EGA_IO_ADDRESS, 2); |
if (sysinfo_value("fb.blinking")) { |
ega_normal_color &= 0x77; |
ega_inverted_color &= 0x77; |
} |
style = NORMAL_COLOR; |
iospace_enable(task_get_id(), (void *) EGA_IO_BASE, 2); |
sz = scr_width * scr_height * 2; |
scr_addr = as_get_mappable_page(sz); |
if (physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE) != 0) |
return -1; |
physmem_map(ega_ph_addr, scr_addr, ALIGN_UP(sz, PAGE_SIZE) >> |
PAGE_WIDTH, AS_AREA_READ | AS_AREA_WRITE); |
async_set_client_connection(ega_client_connection); |
396,6 → 326,6 |
} |
/** |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/fb/main.c |
---|
33,21 → 33,16 |
#include <as.h> |
#include <align.h> |
#include <errno.h> |
#include <stdio.h> |
#include "fb.h" |
#include "sysio.h" |
#include "ega.h" |
#include "msim.h" |
#include "ski.h" |
#include "sgcn.h" |
#include "main.h" |
#define NAME "fb" |
void receive_comm_area(ipc_callid_t callid, ipc_call_t *call, void **area) |
{ |
void *dest; |
dest = as_get_mappable_page(IPC_GET_ARG2(*call)); |
if (ipc_answer_1(callid, EOK, (sysarg_t) dest) == 0) { |
if (*area) |
58,51 → 53,29 |
int main(int argc, char *argv[]) |
{ |
printf(NAME ": HelenOS Framebuffer service\n"); |
ipcarg_t phonead; |
bool initialized = false; |
int initialized = 0; |
#ifdef FB_ENABLED |
if (sysinfo_value("fb.kind") == 1) { |
if (fb_init() == 0) |
initialized = true; |
} |
initialized = 1; |
} |
#endif |
#ifdef EGA_ENABLED |
if ((!initialized) && (sysinfo_value("fb.kind") == 2)) { |
if (!initialized && sysinfo_value("fb.kind") == 2) { |
if (ega_init() == 0) |
initialized = true; |
initialized = 1; |
} |
#endif |
#ifdef MSIM_ENABLED |
if ((!initialized) && (sysinfo_value("fb.kind") == 3)) { |
if (msim_init() == 0) |
initialized = true; |
} |
#endif |
#ifdef SGCN_ENABLED |
if ((!initialized) && (sysinfo_value("fb.kind") == 4)) { |
if (sgcn_init() == 0) |
initialized = true; |
} |
#endif |
#ifdef SKI_ENABLED |
if ((!initialized) && (sysinfo_value("fb") != true)) { |
if (ski_init() == 0) |
initialized = true; |
} |
#endif |
if (!initialized) |
return -1; |
sysio_init(); |
if (ipc_connect_to_me(PHONE_NS, SERVICE_VIDEO, 0, 0, &phonead) != 0) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Never reached */ |
return 0; |
} |
/branches/dd/uspace/srv/fb/sysio.c |
---|
0,0 → 1,198 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @defgroup sysio SysIO |
* @brief HelenOS framebuffer emulation via kernel. |
* @ingroup fbs |
* @{ |
*/ |
/** @file |
*/ |
#include <async.h> |
#include <ipc/fb.h> |
#include <ipc/ipc.h> |
#include <libc.h> |
#include <errno.h> |
#include <string.h> |
#include <libc.h> |
#include <stdio.h> |
#include "sysio.h" |
#define WIDTH 80 |
#define HEIGHT 25 |
/* Allow only 1 connection */ |
static int client_connected = 0; |
static void sysput(char c) |
{ |
__SYSCALL3(SYS_IO, 1, (sysarg_t)&c, (sysarg_t) 1); |
} |
static void sysputs(char *s) |
{ |
while (*s) { |
sysput(*(s++)); |
} |
// __SYSCALL3(SYS_IO, 1, (sysarg_t)s, strlen(s)); |
} |
/** Send clearscreen sequence to console */ |
static void clrscr(void) |
{ |
sysputs("\033[2J"); |
} |
/** Send ansi sequence to console to change cursor position */ |
static void curs_goto(unsigned int row, unsigned int col) |
{ |
char control[20]; |
if (row > 200 || col > 200) |
return; |
snprintf(control, 20, "\033[%d;%df",row+1, col+1); |
sysputs(control); |
} |
static void set_style(int mode) |
{ |
char control[20]; |
snprintf(control, 20, "\033[%dm", mode); |
sysputs(control); |
} |
static void scroll(int i) |
{ |
if (i > 0) { |
curs_goto(HEIGHT-1, 0); |
while (i--) |
sysputs("\033D"); |
} else if (i < 0) { |
curs_goto(0,0); |
while (i++) |
sysputs("\033M"); |
} |
} |
/** ANSI terminal emulation main thread */ |
static void sysio_client_connection(ipc_callid_t iid, ipc_call_t *icall) |
{ |
int retval; |
ipc_callid_t callid; |
ipc_call_t call; |
char c; |
int lastcol=0; |
int lastrow=0; |
int newcol,newrow; |
int fgcolor,bgcolor; |
int i; |
if (client_connected) { |
ipc_answer_0(iid, ELIMIT); |
return; |
} |
client_connected = 1; |
ipc_answer_0(iid, EOK); /* Accept connection */ |
while (1) { |
callid = async_get_call(&call); |
switch (IPC_GET_METHOD(call)) { |
case IPC_M_PHONE_HUNGUP: |
client_connected = 0; |
ipc_answer_0(callid, EOK); |
return; /* Exit thread */ |
case FB_PUTCHAR: |
c = IPC_GET_ARG1(call); |
newrow = IPC_GET_ARG2(call); |
newcol = IPC_GET_ARG3(call); |
if ((lastcol != newcol) || (lastrow != newrow)) |
curs_goto(newrow, newcol); |
lastcol = newcol + 1; |
lastrow = newrow; |
sysput(c); |
retval = 0; |
break; |
case FB_CURSOR_GOTO: |
newrow = IPC_GET_ARG1(call); |
newcol = IPC_GET_ARG2(call); |
curs_goto(newrow, newcol); |
lastrow = newrow; |
lastcol = newcol; |
retval = 0; |
break; |
case FB_GET_CSIZE: |
ipc_answer_2(callid, EOK, HEIGHT, WIDTH); |
continue; |
case FB_CLEAR: |
clrscr(); |
retval = 0; |
break; |
case FB_SET_STYLE: |
fgcolor = IPC_GET_ARG1(call); |
bgcolor = IPC_GET_ARG2(call); |
if (fgcolor < bgcolor) |
set_style(0); |
else |
set_style(7); |
retval = 0; |
break; |
case FB_SCROLL: |
i = IPC_GET_ARG1(call); |
if ((i > HEIGHT) || (i < -HEIGHT)) { |
retval = EINVAL; |
break; |
} |
scroll(i); |
curs_goto(lastrow, lastcol); |
retval = 0; |
break; |
default: |
retval = ENOENT; |
} |
ipc_answer_0(callid, retval); |
} |
} |
/** ANSI terminal emulation initialization */ |
void sysio_init(void) |
{ |
async_set_client_connection(sysio_client_connection); |
clrscr(); |
curs_goto(0,0); |
/* Set scrolling region to 0-25 lines */ |
sysputs("\033[0;25r"); |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/fb/ppm.c |
---|
92,23 → 92,23 |
int i; |
unsigned int color; |
unsigned int coef; |
/* Read magic */ |
if ((data[0] != 'P') || (data[1] != '6')) |
if (data[0] != 'P' || data[1] != '6') |
return EINVAL; |
data += 2; |
data+=2; |
skip_whitespace(&data); |
read_num(&data, &width); |
skip_whitespace(&data); |
read_num(&data, &height); |
read_num(&data,&height); |
skip_whitespace(&data); |
read_num(&data, &maxcolor); |
read_num(&data,&maxcolor); |
data++; |
if ((maxcolor == 0) || (maxcolor > 255) || (width * height > datasz)) |
if (maxcolor == 0 || maxcolor > 255 || width * height > datasz) { |
return EINVAL; |
} |
coef = 255 / maxcolor; |
if (coef * maxcolor > 255) |
coef -= 1; |
125,6 → 125,6 |
(*putpixel)(vport, sx + (i % width), sy + (i / width), color); |
data += 3; |
} |
return 0; |
} |
/branches/dd/uspace/srv/fb/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../libipc/include |
44,69 → 43,50 |
OUTPUT = fb |
SOURCES = \ |
main.c \ |
sysio.c \ |
ppm.c |
ifneq ($(UARCH),ia64) |
ifneq ($(ARCH), ia64) |
SOURCES += fb.c \ |
font-8x16.c |
CFLAGS += -DFB_ENABLED |
endif |
ifeq ($(UARCH),ia32) |
ifeq ($(ARCH), ia32) |
SOURCES += ega.c |
CFLAGS += -DEGA_ENABLED |
endif |
ifeq ($(UARCH),ia64) |
SOURCES += ega.c \ |
ski.c \ |
serial_console.c |
CFLAGS += -DSKI_ENABLED |
CFLAGS += -DEGA_ENABLED |
endif |
ifeq ($(UARCH),amd64) |
ifeq ($(ARCH), amd64) |
SOURCES += ega.c |
CFLAGS += -DEGA_ENABLED |
endif |
ifeq ($(UARCH),mips32) |
SOURCES += msim.c \ |
serial_console.c |
CFLAGS += -DMSIM_ENABLED |
ifeq ($(ARCH), mips32) |
CFLAGS += -DFB_INVERT_ENDIAN |
endif |
ifeq ($(UARCH),sparc64) |
SOURCES += sgcn.c \ |
serial_console.c |
CFLAGS += -DSGCN_ENABLED |
endif |
CFLAGS += -D$(ARCH) |
CFLAGS += -D$(UARCH) |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld -e __entry_driver $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/fb/font-8x16.h |
---|
29,11 → 29,9 |
#ifndef FB_FONT_8X16_H_ |
#define FB_FONT_8X16_H_ |
#define FONT_GLYPHS 256 |
#define FONT_WIDTH 8 |
#define FONT_SCANLINES 16 |
#define FONT_GLIPHS 256 |
#define FONT_SCANLINES 16 |
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES]; |
extern unsigned char fb_font[FONT_GLYPHS * FONT_SCANLINES]; |
#endif |
/branches/dd/uspace/srv/fb/sysio.h |
---|
0,0 → 1,45 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup sysio |
* @brief HelenOS framebuffer emulation via kernel. |
* @ingroup fbs |
* @{ |
*/ |
/** @file |
*/ |
#ifndef FB_SYSIO_H_ |
#define FB_SYSIO_H_ |
extern void sysio_init(void); |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/fb/fb.h |
---|
29,7 → 29,7 |
/** @addtogroup fb |
* @ingroup fbs |
* @{ |
*/ |
*/ |
/** @file |
*/ |
36,10 → 36,8 |
#ifndef FB_FB_H_ |
#define FB_FB_H_ |
#include <stdint.h> |
typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, int); |
typedef void (* putpixel_cb_t)(void *, unsigned int, unsigned int, uint32_t); |
extern int fb_init(void); |
#endif |
/branches/dd/uspace/srv/fb/font-8x16.c |
---|
28,7 → 28,7 |
#include "font-8x16.h" |
unsigned char fb_font[FONT_GLYPHS * FONT_SCANLINES] = { |
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = { |
/* 0 0x00 '^@' */ |
0x00, /* 00000000 */ |
/branches/dd/uspace/srv/kbd/layout/us_dvorak.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/layout/us_qwerty.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/ctl/sun.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/ctl/gxe_fb.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/ctl/pc.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/ctl/stty.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/msim.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/i8042.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/ski.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/z8530.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/sgcn.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/dummy.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/i8042.h |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/gxemul.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/port/ns16550.c |
---|
File deleted |
/branches/dd/uspace/srv/kbd/generic/kbd.c |
---|
37,99 → 37,48 |
#include <ipc/ipc.h> |
#include <ipc/services.h> |
#include <sysinfo.h> |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <stdio.h> |
#include <ipc/ns.h> |
#include <async.h> |
#include <errno.h> |
#include <arch/kbd.h> |
#include <kbd.h> |
#include <libadt/fifo.h> |
#include <kbd/kbd.h> |
#include <kbd/keycode.h> |
#include <kbd.h> |
#include <key_buffer.h> |
#include <kbd_port.h> |
#include <kbd_ctl.h> |
#include <layout.h> |
#include <async.h> |
#include <keys.h> |
#define NAME "kbd" |
#define NAME "KBD" |
int cons_connected = 0; |
int phone2cons = -1; |
keybuffer_t keybuffer; |
keybuffer_t keybuffer; |
/** Currently active modifiers. */ |
static unsigned mods = KM_NUM_LOCK; |
/** Currently pressed lock keys. We track these to tackle autorepeat. */ |
static unsigned lock_keys; |
int cir_service = 0; |
int cir_phone = -1; |
void kbd_push_scancode(int scancode) |
static void irq_handler(ipc_callid_t iid, ipc_call_t *call) |
{ |
/* printf("scancode: 0x%x\n", scancode);*/ |
kbd_ctl_parse_scancode(scancode); |
} |
int chr; |
void kbd_push_ev(int type, unsigned int key) |
{ |
kbd_event_t ev; |
unsigned mod_mask; |
#ifdef MOUSE_ENABLED |
if (mouse_arch_process(phone2cons, call)) |
return; |
#endif |
kbd_arch_process(&keybuffer, call); |
switch (key) { |
case KC_LCTRL: mod_mask = KM_LCTRL; break; |
case KC_RCTRL: mod_mask = KM_RCTRL; break; |
case KC_LSHIFT: mod_mask = KM_LSHIFT; break; |
case KC_RSHIFT: mod_mask = KM_RSHIFT; break; |
case KC_LALT: mod_mask = KM_LALT; break; |
case KC_RALT: mod_mask = KM_RALT; break; |
default: mod_mask = 0; break; |
} |
if (cons_connected && phone2cons != -1) { |
/* |
* recode to ASCII - one interrupt can produce more than one |
* code so result is stored in fifo |
*/ |
while (!keybuffer_empty(&keybuffer)) { |
if (!keybuffer_pop(&keybuffer, (int *)&chr)) |
break; |
if (mod_mask != 0) { |
if (type == KE_PRESS) |
mods = mods | mod_mask; |
else |
mods = mods & ~mod_mask; |
} |
switch (key) { |
case KC_CAPS_LOCK: mod_mask = KM_CAPS_LOCK; break; |
case KC_NUM_LOCK: mod_mask = KM_NUM_LOCK; break; |
case KC_SCROLL_LOCK: mod_mask = KM_SCROLL_LOCK; break; |
default: mod_mask = 0; break; |
} |
if (mod_mask != 0) { |
if (type == KE_PRESS) { |
/* |
* Only change lock state on transition from released |
* to pressed. This prevents autorepeat from messing |
* up the lock state. |
*/ |
mods = mods ^ (mod_mask & ~lock_keys); |
lock_keys = lock_keys | mod_mask; |
} else { |
lock_keys = lock_keys & ~mod_mask; |
async_msg_1(phone2cons, KBD_PUSHCHAR, chr); |
} |
} |
/* |
printf("type: %d\n", type); |
printf("mods: 0x%x\n", mods); |
printf("keycode: %u\n", key); |
*/ |
ev.type = type; |
ev.key = key; |
ev.mods = mods; |
ev.c = layout_parse_ev(&ev); |
async_msg_4(phone2cons, KBD_EVENT, ev.type, ev.key, ev.mods, ev.c); |
} |
static void console_connection(ipc_callid_t iid, ipc_call_t *icall) |
172,24 → 121,10 |
int main(int argc, char **argv) |
{ |
printf(NAME ": HelenOS Keyboard service\n"); |
ipcarg_t phonead; |
if (sysinfo_value("kbd.cir.fhc") == 1) |
cir_service = SERVICE_FHC; |
else if (sysinfo_value("kbd.cir.obio") == 1) |
cir_service = SERVICE_OBIO; |
if (cir_service) { |
while (cir_phone < 0) { |
cir_phone = ipc_connect_me_to_blocking(PHONE_NS, cir_service, |
0, 0); |
} |
} |
/* Initialize port driver. */ |
if (kbd_port_init()) |
/* Initialize arch dependent parts */ |
if (kbd_arch_init()) |
return -1; |
/* Initialize key buffer */ |
196,15 → 131,14 |
keybuffer_init(&keybuffer); |
async_set_client_connection(console_connection); |
/* Register service at nameserver. */ |
async_set_interrupt_received(irq_handler); |
/* Register service at nameserver */ |
if (ipc_connect_to_me(PHONE_NS, SERVICE_KEYBOARD, 0, 0, &phonead) != 0) |
return -1; |
printf(NAME ": Accepting connections\n"); |
async_manager(); |
/* Not reached. */ |
/* Never reached */ |
return 0; |
} |
211,3 → 145,4 |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/generic/key_buffer.c |
---|
40,7 → 40,7 |
/** Clear key buffer. |
*/ |
void keybuffer_free(keybuffer_t *keybuffer) |
void keybuffer_free(keybuffer_t *keybuffer) |
{ |
futex_down(&keybuffer_futex); |
keybuffer->head = 0; |
75,18 → 75,15 |
return (keybuffer->items == 0); |
} |
/** Push key event to key buffer. |
* |
* If the buffer is full, the event is ignored. |
* |
* @param keybuffer The keybuffer. |
* @param ev The event to push. |
/** Push key to key buffer. |
* If buffer is full, character is ignored. |
* @param key code of stored key |
*/ |
void keybuffer_push(keybuffer_t *keybuffer, const kbd_event_t *ev) |
void keybuffer_push(keybuffer_t *keybuffer, int key) |
{ |
futex_down(&keybuffer_futex); |
if (keybuffer->items < KEYBUFFER_SIZE) { |
keybuffer->fifo[keybuffer->tail] = *ev; |
keybuffer->fifo[keybuffer->tail] = key; |
keybuffer->tail = (keybuffer->tail + 1) % KEYBUFFER_SIZE; |
keybuffer->items++; |
} |
93,25 → 90,16 |
futex_up(&keybuffer_futex); |
} |
void keybuffer_push0(keybuffer_t *keybuffer, int c) |
{ |
kbd_event_t ev; |
ev.key = c; ev.mods = 0; ev.c = c; |
keybuffer_push(keybuffer, &ev); |
} |
/** Pop event from buffer. |
* |
* @param edst Pointer to where the event should be saved. |
* @return Zero on empty buffer, nonzero otherwise. |
/** Pop character from buffer. |
* @param c pointer to space where to store character from buffer. |
* @return zero on empty buffer, nonzero else |
*/ |
int keybuffer_pop(keybuffer_t *keybuffer, kbd_event_t *edst) |
int keybuffer_pop(keybuffer_t *keybuffer, int *c) |
{ |
futex_down(&keybuffer_futex); |
if (keybuffer->items > 0) { |
keybuffer->items--; |
*edst = (keybuffer->fifo[keybuffer->head]) ; |
*c = (keybuffer->fifo[keybuffer->head]) ; |
keybuffer->head = (keybuffer->head + 1) % KEYBUFFER_SIZE; |
futex_up(&keybuffer_futex); |
return 1; |
/branches/dd/uspace/srv/kbd/arch/ia32/src/mouse.c |
---|
0,0 → 1,117 |
/* |
* Copyright (c) 2006 Ondrej Palkovsky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <ipc/ipc.h> |
#include <async.h> |
#include <kbd.h> |
#include <keys.h> |
#define i8042_MOUSE_DATA 0x20 |
#define BUFSIZE 3 |
typedef struct { |
union { |
unsigned char data[BUFSIZE]; |
struct { |
unsigned leftbtn : 1; |
unsigned rightbtn : 1; |
unsigned middlebtn : 1; |
unsigned isone : 1; /* Always one */ |
unsigned xsign : 1; |
unsigned ysign : 1; |
unsigned xovfl : 1; |
unsigned yovfl : 1; |
unsigned char x; |
unsigned char y; |
} val; |
}u; |
}ps2packet_t; |
static ps2packet_t buf; |
static int bufpos = 0; |
static int leftbtn = 0; |
static int rightbtn = 0; |
static int middlebtn = 0; |
/** Convert 9-bit 2-complement signed number to integer */ |
static int bit9toint(int sign, unsigned char data) |
{ |
int tmp; |
if (!sign) |
return data; |
tmp = ((unsigned char)~data) + 1; |
return -tmp; |
} |
/** Process mouse data |
* |
* @return True if mouse command was recognized and processed |
*/ |
int mouse_arch_process(int phoneid, ipc_call_t *call) |
{ |
int status = IPC_GET_ARG1(*call); |
int data = IPC_GET_ARG2(*call); |
int x,y; |
if (!(status & i8042_MOUSE_DATA)) |
return 0; |
/* Check that we have not lost synchronization */ |
if (bufpos == 0 && !(data & 0x8)) |
return 1; /* Synchro lost, ignore byte */ |
buf.u.data[bufpos++] = data; |
if (bufpos == BUFSIZE) { |
bufpos = 0; |
if (phoneid != -1) { |
if (buf.u.val.leftbtn ^ leftbtn) { |
leftbtn = buf.u.val.leftbtn; |
async_msg_1(phoneid, KBD_MS_LEFT, leftbtn); |
} |
if (buf.u.val.rightbtn & rightbtn) { |
rightbtn = buf.u.val.middlebtn; |
async_msg_1(phoneid, KBD_MS_RIGHT, rightbtn); |
} |
if (buf.u.val.rightbtn & rightbtn) { |
middlebtn = buf.u.val.middlebtn; |
async_msg_1(phoneid, KBD_MS_MIDDLE, middlebtn); |
} |
x = bit9toint(buf.u.val.xsign, buf.u.val.x); |
y = bit9toint(buf.u.val.ysign, buf.u.val.y); |
if (x || y) |
async_msg_2(phoneid, KBD_MS_MOVE, (ipcarg_t)x, |
(ipcarg_t)(-y)); |
} |
} |
return 1; |
} |
/branches/dd/uspace/srv/kbd/arch/ia32/src/kbd.c |
---|
0,0 → 1,166 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdia32 ia32 |
* @brief HelenOS ia32 / amd64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
* @ingroup kbdamd64 |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <unistd.h> |
#include <kbd.h> |
#include <keys.h> |
#include <genarch/kbd.h> |
#include <sysinfo.h> |
/* Interesting bits for status register */ |
#define i8042_OUTPUT_FULL 0x1 |
#define i8042_INPUT_FULL 0x2 |
#define i8042_MOUSE_DATA 0x20 |
/* Command constants */ |
#define i8042_CMD_KBD 0x60 |
#define i8042_CMD_MOUSE 0xd4 |
/* Keyboard cmd byte */ |
#define i8042_KBD_IE 0x1 |
#define i8042_MOUSE_IE 0x2 |
#define i8042_KBD_DISABLE 0x10 |
#define i8042_MOUSE_DISABLE 0x20 |
#define i8042_KBD_TRANSLATE 0x40 |
/* Mouse constants */ |
#define MOUSE_OUT_INIT 0xf4 |
#define MOUSE_ACK 0xfa |
#define KEY_RELEASE 0x80 |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
irq_cmd_t i8042_cmds[2] = { |
{ CMD_PORT_READ_1, (void *) 0x64, 0, 1 }, |
{ CMD_PORT_READ_1, (void *) 0x60, 0, 2 } |
}; |
irq_code_t i8042_kbd = { |
2, |
i8042_cmds |
}; |
static void wait_ready(void) { |
while (i8042_status_read() & i8042_INPUT_FULL) |
; |
} |
/** Register uspace irq handler |
* @return |
*/ |
int kbd_arch_init(void) |
{ |
int i; |
int mouseenabled = 0; |
iospace_enable(task_get_id(), (void *) i8042_DATA, 5); |
/* Disable kbd, enable mouse */ |
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_data_write(i8042_KBD_DISABLE); |
wait_ready(); |
/* Flush all current IO */ |
while (i8042_status_read() & i8042_OUTPUT_FULL) |
i8042_data_read(); |
/* Initialize mouse */ |
i8042_command_write(i8042_CMD_MOUSE); |
wait_ready(); |
i8042_data_write(MOUSE_OUT_INIT); |
wait_ready(); |
int mouseanswer = 0; |
for (i=0;i < 1000; i++) { |
int status = i8042_status_read(); |
if (status & i8042_OUTPUT_FULL) { |
int data = i8042_data_read(); |
if (status & i8042_MOUSE_DATA) { |
mouseanswer = data; |
break; |
} |
} |
usleep(1000); |
} |
if (mouseanswer == MOUSE_ACK) { |
/* enable mouse */ |
mouseenabled = 1; |
ipc_register_irq(sysinfo_value("mouse.inr"), sysinfo_value("mouse.devno"), 0, &i8042_kbd); |
} |
/* Enable kbd */ |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &i8042_kbd); |
int newcontrol = i8042_KBD_IE | i8042_KBD_TRANSLATE; |
if (mouseenabled) |
newcontrol |= i8042_MOUSE_IE; |
i8042_command_write(i8042_CMD_KBD); |
wait_ready(); |
i8042_data_write(newcontrol); |
wait_ready(); |
return 0; |
} |
/** Process keyboard & mouse events */ |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
int status = IPC_GET_ARG1(*call); |
if ((status & i8042_MOUSE_DATA)) |
return 0; |
int scan_code = IPC_GET_ARG2(*call); |
if (scan_code & KEY_RELEASE) |
key_released(keybuffer, scan_code ^ KEY_RELEASE); |
else |
key_pressed(keybuffer, scan_code); |
return 1; |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ia32/src/scanc.c |
---|
0,0 → 1,202 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdia32 |
* @brief Scancodes for PC keyboards. |
* @{ |
*/ |
/** @file |
* @ingroup kbdamd64 |
*/ |
#include <genarch/scanc.h> |
/** Primary meaning of scancodes. */ |
int sc_primary_map[] = { |
SPECIAL, /* 0x00 */ |
SPECIAL, /* 0x01 - Esc */ |
'1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', |
'\b', /* 0x0e - Backspace */ |
'\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', |
'`', |
SPECIAL, /* 0x2a - LShift */ |
'\\', |
'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
(FUNCTION_KEYS | 1), /* 0x3b - F1 */ |
(FUNCTION_KEYS | 2), /* 0x3c - F2 */ |
(FUNCTION_KEYS | 3), /* 0x3d - F3 */ |
(FUNCTION_KEYS | 4), /* 0x3e - F4 */ |
(FUNCTION_KEYS | 5), /* 0x3f - F5 */ |
(FUNCTION_KEYS | 6), /* 0x40 - F6 */ |
(FUNCTION_KEYS | 7), /* 0x41 - F7 */ |
(FUNCTION_KEYS | 8), /* 0x42 - F8 */ |
(FUNCTION_KEYS | 9), /* 0x43 - F9 */ |
(FUNCTION_KEYS | 10), /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
(FUNCTION_KEYS | 11), /* 0x57 - F11 */ |
(FUNCTION_KEYS | 12), /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** Secondary meaning of scancodes. */ |
int sc_secondary_map[] = { |
SPECIAL, /* 0x00 */ |
0x1b, /* 0x01 - Esc */ |
'!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', |
SPECIAL, /* 0x0e - Backspace */ |
'\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', |
SPECIAL, /* 0x1d - LCtrl */ |
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', |
'~', |
SPECIAL, /* 0x2a - LShift */ |
'|', |
'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', |
SPECIAL, /* 0x36 - RShift */ |
'*', |
SPECIAL, /* 0x38 - LAlt */ |
' ', |
SPECIAL, /* 0x3a - CapsLock */ |
SPECIAL, /* 0x3b - F1 */ |
SPECIAL, /* 0x3c - F2 */ |
SPECIAL, /* 0x3d - F3 */ |
SPECIAL, /* 0x3e - F4 */ |
SPECIAL, /* 0x3f - F5 */ |
SPECIAL, /* 0x40 - F6 */ |
SPECIAL, /* 0x41 - F7 */ |
SPECIAL, /* 0x42 - F8 */ |
SPECIAL, /* 0x43 - F9 */ |
SPECIAL, /* 0x44 - F10 */ |
SPECIAL, /* 0x45 - NumLock */ |
SPECIAL, /* 0x46 - ScrollLock */ |
'7', '8', '9', '-', |
'4', '5', '6', '+', |
'1', '2', '3', |
'0', '.', |
SPECIAL, /* 0x54 - Alt-SysRq */ |
SPECIAL, /* 0x55 - F11/F12/PF1/FN */ |
SPECIAL, /* 0x56 - unlabelled key next to LAlt */ |
SPECIAL, /* 0x57 - F11 */ |
SPECIAL, /* 0x58 - F12 */ |
SPECIAL, /* 0x59 */ |
SPECIAL, /* 0x5a */ |
SPECIAL, /* 0x5b */ |
SPECIAL, /* 0x5c */ |
SPECIAL, /* 0x5d */ |
SPECIAL, /* 0x5e */ |
SPECIAL, /* 0x5f */ |
SPECIAL, /* 0x60 */ |
SPECIAL, /* 0x61 */ |
SPECIAL, /* 0x62 */ |
SPECIAL, /* 0x63 */ |
SPECIAL, /* 0x64 */ |
SPECIAL, /* 0x65 */ |
SPECIAL, /* 0x66 */ |
SPECIAL, /* 0x67 */ |
SPECIAL, /* 0x68 */ |
SPECIAL, /* 0x69 */ |
SPECIAL, /* 0x6a */ |
SPECIAL, /* 0x6b */ |
SPECIAL, /* 0x6c */ |
SPECIAL, /* 0x6d */ |
SPECIAL, /* 0x6e */ |
SPECIAL, /* 0x6f */ |
SPECIAL, /* 0x70 */ |
SPECIAL, /* 0x71 */ |
SPECIAL, /* 0x72 */ |
SPECIAL, /* 0x73 */ |
SPECIAL, /* 0x74 */ |
SPECIAL, /* 0x75 */ |
SPECIAL, /* 0x76 */ |
SPECIAL, /* 0x77 */ |
SPECIAL, /* 0x78 */ |
SPECIAL, /* 0x79 */ |
SPECIAL, /* 0x7a */ |
SPECIAL, /* 0x7b */ |
SPECIAL, /* 0x7c */ |
SPECIAL, /* 0x7d */ |
SPECIAL, /* 0x7e */ |
SPECIAL, /* 0x7f */ |
}; |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ia32/include/kbd.h |
---|
0,0 → 1,76 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdamd64 amd64 |
* @brief HelenOS ia32 / amd64 arch dependent parts of uspace keyboard and mouse handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
* @ingroup kbdia32 |
*/ |
#ifndef KBD_ia32_KBD_H_ |
#define KBD_ia32_KBD_H_ |
#include <ddi.h> |
#include <libarch/ddi.h> |
#define i8042_DATA 0x60 |
#define i8042_STATUS 0X64 |
typedef unsigned char u8; |
typedef short u16; |
static inline void i8042_data_write(u8 data) |
{ |
outb(i8042_DATA, data); |
} |
static inline u8 i8042_data_read(void) |
{ |
return inb(i8042_DATA); |
} |
static inline u8 i8042_status_read(void) |
{ |
return inb(i8042_STATUS); |
} |
static inline void i8042_command_write(u8 command) |
{ |
outb(i8042_STATUS, command); |
} |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ia32/include/scanc.h |
---|
0,0 → 1,59 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdia32 |
* @{ |
*/ |
/** @file |
* @ingroup kbdamd64 |
*/ |
#ifndef KBD_ia32_SCANC_H_ |
#define KBD_ia32_SCANC_H_ |
/** Scancodes. */ |
#define SC_ESC 0x01 |
#define SC_BACKSPACE 0x0e |
#define SC_LSHIFT 0x2a |
#define SC_RSHIFT 0x36 |
#define SC_CAPSLOCK 0x3a |
#define SC_SPEC_ESCAPE 0xe0 |
#define SC_LEFTARR 0x4b |
#define SC_RIGHTARR 0x4d |
#define SC_UPARR 0x48 |
#define SC_DOWNARR 0x50 |
#define SC_DELETE 0x53 |
#define SC_HOME 0x47 |
#define SC_END 0x4f |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/sparc64/src/kbd.c |
---|
0,0 → 1,117 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdsparc64 sparc64 |
* @brief HelenOS sparc64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
#include <stdio.h> |
#include <sys/types.h> |
#include <genarch/kbd.h> |
#define KBD_KEY_RELEASE 0x80 |
#define KBD_ALL_KEYS_UP 0x7f |
/** Top-half pseudocode for z8530. */ |
irq_cmd_t z8530_cmds[] = { |
{ |
CMD_MEM_READ_1, |
0, /**< Address. Will be patched in run-time. */ |
0, /**< Value. Not used. */ |
1 /**< Arg 1 will contain the result. */ |
} |
}; |
irq_code_t z8530_kbd = { |
1, |
z8530_cmds |
}; |
/** Top-half pseudocode for ns16550. */ |
irq_cmd_t ns16550_cmds[] = { |
{ |
CMD_MEM_READ_1, |
0, /**< Address. Will be patched in run-time. */ |
0, /**< Value. Not used. */ |
1 /**< Arg 1 will contain the result. */ |
} |
}; |
irq_code_t ns16550_kbd = { |
1, |
ns16550_cmds |
}; |
#define KBD_Z8530 1 |
#define KBD_NS16550 2 |
int kbd_arch_init(void) |
{ |
int type = sysinfo_value("kbd.type"); |
switch (type) { |
case KBD_Z8530: |
z8530_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual") + 6; |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &z8530_kbd); |
break; |
case KBD_NS16550: |
ns16550_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual"); |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ns16550_kbd); |
break; |
default: |
break; |
} |
return 0; |
} |
/** Process keyboard events */ |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
int scan_code = IPC_GET_ARG1(*call); |
if (scan_code == KBD_ALL_KEYS_UP) |
return 1; |
if (scan_code & KBD_KEY_RELEASE) |
key_released(keybuffer, scan_code ^ KBD_KEY_RELEASE); |
else |
key_pressed(keybuffer, scan_code); |
return 1; |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/sparc64/src/scanc.c |
---|
0,0 → 1,304 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for Sun keyboards. |
*/ |
#include <genarch/scanc.h> |
/** Primary meaning of scancodes. */ |
int sc_primary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = FUNCTION_KEYS + 1, /* F1 */ |
[0x06] = FUNCTION_KEYS + 2, /* F2 */ |
[0x07] = FUNCTION_KEYS + 10, /* F10 */ |
[0x08] = FUNCTION_KEYS + 3, /* F3 */ |
[0x09] = FUNCTION_KEYS + 11, /* F11 */ |
[0x0a] = FUNCTION_KEYS + 4, /* F4 */ |
[0x0b] = FUNCTION_KEYS + 12, /* F12 */ |
[0x0c] = FUNCTION_KEYS + 5, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = FUNCTION_KEYS + 6, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = FUNCTION_KEYS + 7, /* F7 */ |
[0x11] = FUNCTION_KEYS + 8, /* F8 */ |
[0x12] = FUNCTION_KEYS + 9, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* Esc */ |
[0x1e] = '1', |
[0x1f] = '2', |
[0x20] = '3', |
[0x21] = '4', |
[0x22] = '5', |
[0x23] = '6', |
[0x24] = '7', |
[0x25] = '8', |
[0x26] = '9', |
[0x27] = '0', |
[0x28] = '-', |
[0x29] = '=', |
[0x2a] = '`', |
[0x2b] = '\b', /* Backspace */ |
[0x2c] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* Home */ |
[0x35] = '\t', /* Tab */ |
[0x36] = 'q', |
[0x37] = 'w', |
[0x38] = 'e', |
[0x39] = 'r', |
[0x3a] = 't', |
[0x3b] = 'y', |
[0x3c] = 'u', |
[0x3d] = 'i', |
[0x3e] = 'o', |
[0x3f] = 'p', |
[0x40] = '[', |
[0x41] = ']', |
[0x42] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = SPECIAL, /* Control */ |
[0x4d] = 'a', |
[0x4e] = 's', |
[0x4f] = 'd', |
[0x50] = 'f', |
[0x51] = 'g', |
[0x52] = 'h', |
[0x53] = 'j', |
[0x54] = 'k', |
[0x55] = 'l', |
[0x56] = ';', |
[0x57] = '\'', |
[0x58] = '\\', |
[0x59] = '\n', /* Enter */ |
[0x5a] = '\n', /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'z', |
[0x65] = 'x', |
[0x66] = 'c', |
[0x67] = 'v', |
[0x68] = 'b', |
[0x69] = 'n', |
[0x6a] = 'm', |
[0x6b] = ',', |
[0x6c] = '.', |
[0x6d] = '/', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** Secondary meaning of scancodes. */ |
int sc_secondary_map[] = { |
[0x00] = SPECIAL, |
[0x01] = SPECIAL, |
[0x02] = SPECIAL, |
[0x03] = SPECIAL, |
[0x04] = SPECIAL, |
[0x05] = SPECIAL, /* F1 */ |
[0x06] = SPECIAL, /* F2 */ |
[0x07] = SPECIAL, /* F10 */ |
[0x08] = SPECIAL, /* F3 */ |
[0x09] = SPECIAL, /* F11 */ |
[0x0a] = SPECIAL, /* F4 */ |
[0x0b] = SPECIAL, /* F12 */ |
[0x0c] = SPECIAL, /* F5 */ |
[0x0d] = SPECIAL, /* RAlt */ |
[0x0e] = SPECIAL, /* F6 */ |
[0x0f] = SPECIAL, |
[0x10] = SPECIAL, /* F7 */ |
[0x11] = SPECIAL, /* F8 */ |
[0x12] = SPECIAL, /* F9 */ |
[0x13] = SPECIAL, /* LAlt */ |
[0x14] = SPECIAL, /* Up Arrow */ |
[0x15] = SPECIAL, /* Pause */ |
[0x16] = SPECIAL, |
[0x17] = SPECIAL, /* Scroll Lock */ |
[0x18] = SPECIAL, /* Left Arrow */ |
[0x19] = SPECIAL, |
[0x1a] = SPECIAL, |
[0x1b] = SPECIAL, /* Down Arrow */ |
[0x1c] = SPECIAL, /* Right Arrow */ |
[0x1d] = SPECIAL, /* Esc */ |
[0x1e] = '!', |
[0x1f] = '@', |
[0x20] = '#', |
[0x21] = '$', |
[0x22] = '%', |
[0x23] = '^', |
[0x24] = '&', |
[0x25] = '*', |
[0x26] = '(', |
[0x27] = ')', |
[0x28] = '_', |
[0x29] = '+', |
[0x2a] = '~', |
[0x2b] = SPECIAL, /* Backspace */ |
[0x2c] = SPECIAL, /* Insert */ |
[0x2d] = SPECIAL, |
[0x2e] = '/', /* numeric keypad */ |
[0x2f] = '*', /* numeric keypad */ |
[0x30] = SPECIAL, |
[0x31] = SPECIAL, |
[0x32] = '.', /* numeric keypad */ |
[0x33] = SPECIAL, |
[0x34] = SPECIAL, /* Home */ |
[0x35] = SPECIAL, /* Tab */ |
[0x36] = 'Q', |
[0x37] = 'W', |
[0x38] = 'E', |
[0x39] = 'R', |
[0x3a] = 'T', |
[0x3b] = 'Y', |
[0x3c] = 'U', |
[0x3d] = 'I', |
[0x3e] = 'O', |
[0x3f] = 'P', |
[0x40] = '{', |
[0x41] = '}', |
[0x42] = SPECIAL, /* Del */ |
[0x43] = SPECIAL, |
[0x44] = '7', /* numeric keypad */ |
[0x45] = '8', /* numeric keypad */ |
[0x46] = '9', /* numeric keypad */ |
[0x47] = '-', /* numeric keypad */ |
[0x48] = SPECIAL, |
[0x49] = SPECIAL, |
[0x4a] = SPECIAL, /* End */ |
[0x4b] = SPECIAL, |
[0x4c] = SPECIAL, /* Control */ |
[0x4d] = 'A', |
[0x4e] = 'S', |
[0x4f] = 'D', |
[0x50] = 'F', |
[0x51] = 'G', |
[0x52] = 'H', |
[0x53] = 'J', |
[0x54] = 'K', |
[0x55] = 'L', |
[0x56] = ':', |
[0x57] = '"', |
[0x58] = '|', |
[0x59] = SPECIAL, /* Enter */ |
[0x5a] = SPECIAL, /* Enter on numeric keypad */ |
[0x5b] = '4', /* numeric keypad */ |
[0x5c] = '5', /* numeric keypad */ |
[0x5d] = '6', /* numeric keypad */ |
[0x5e] = '0', /* numeric keypad */ |
[0x5f] = SPECIAL, |
[0x60] = SPECIAL, /* Page Up */ |
[0x61] = SPECIAL, |
[0x62] = SPECIAL, /* Num Lock */ |
[0x63] = SPECIAL, /* LShift */ |
[0x64] = 'Z', |
[0x65] = 'X', |
[0x66] = 'C', |
[0x67] = 'V', |
[0x68] = 'B', |
[0x69] = 'N', |
[0x6a] = 'M', |
[0x6b] = '<', |
[0x6c] = '>', |
[0x6d] = '?', |
[0x6e] = SPECIAL, /* RShift */ |
[0x6f] = SPECIAL, |
[0x70] = '1', /* numeric keypad */ |
[0x71] = '2', /* numeric keypad */ |
[0x72] = '3', /* numeric keypad */ |
[0x73] = SPECIAL, |
[0x74] = SPECIAL, |
[0x75] = SPECIAL, |
[0x76] = SPECIAL, |
[0x77] = SPECIAL, /* Caps Lock */ |
[0x78] = SPECIAL, |
[0x79] = ' ', |
[0x7a] = SPECIAL, |
[0x7b] = SPECIAL, /* Page Down */ |
[0x7c] = SPECIAL, |
[0x7d] = '+', /* numeric key pad */ |
[0x7e] = SPECIAL, |
[0x7f] = SPECIAL |
}; |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/sparc64/include/kbd.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdsparc64 sparc64 |
* @brief HelenOS sparc64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_sparc64_KBD_H_ |
#define KBD_sparc64_KBD_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/sparc64/include/scanc.h |
---|
0,0 → 1,57 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup genarch |
* @{ |
*/ |
/** |
* @file |
* @brief Scan codes for sun keyboards. |
*/ |
#ifndef KBD_SCANC_SUN_H_ |
#define KBD_SCANC_SUN_H_ |
#define SC_ESC 0x1d |
#define SC_BACKSPACE 0x2b |
#define SC_LSHIFT 0x63 |
#define SC_RSHIFT 0x6e |
#define SC_CAPSLOCK 0x77 |
#define SC_SPEC_ESCAPE 0xe0 /* ??? */ |
#define SC_LEFTARR 0x18 |
#define SC_RIGHTARR 0x1c |
#define SC_UPARR 0x14 |
#define SC_DOWNARR 0x1b |
#define SC_DELETE 0x42 |
#define SC_HOME 0x34 |
#define SC_END 0x4a |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/arm32/include/kbd.h |
---|
0,0 → 1,42 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdarm32 |
* @{ |
*/ |
/** @file |
* @brief Empty. |
*/ |
#ifndef KBD_arm32_KBD_H_ |
#define KBD_arm32_KBD_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/arm32/src/kbd.c |
---|
0,0 → 1,40 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdarm32 arm32 |
* @brief HelenOS arm32 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
* @brief Empty, required by generic Makefile. |
*/ |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/arm32/src/kbd_gxemul.c |
---|
0,0 → 1,424 |
/* |
* Copyright (c) 2007 Michal Kebrt |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdarm32gxemul GXemul |
* @brief HelenOS arm32 GXEmul uspace keyboard handler. |
* @ingroup kbdarm32 |
* @{ |
*/ |
/** @file |
* @brief GXemul uspace keyboard handler. |
*/ |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
#include <bool.h> |
/* GXemul key codes in no-framebuffer mode. */ |
#define GXEMUL_KEY_F1 0x504f1bL |
#define GXEMUL_KEY_F2 0x514f1bL |
#define GXEMUL_KEY_F3 0x524f1bL |
#define GXEMUL_KEY_F4 0x534f1bL |
#define GXEMUL_KEY_F5 0x35315b1bL |
#define GXEMUL_KEY_F6 0x37315b1bL |
#define GXEMUL_KEY_F7 0x38315b1bL |
#define GXEMUL_KEY_F8 0x39315b1bL |
#define GXEMUL_KEY_F9 0x30325b1bL |
#define GXEMUL_KEY_F10 0x31325b1bL |
#define GXEMUL_KEY_F11 0x33325d1bL |
#define GXEMUL_KEY_F12 0x34325b1bL |
/** Start code of F5-F12 keys. */ |
#define GXEMUL_KEY_F5_F12_START_CODE 0x7e |
/* GXemul key codes in framebuffer mode. */ |
#define GXEMUL_FB_KEY_F1 0x504f5b1bL |
#define GXEMUL_FB_KEY_F2 0x514f5b1bL |
#define GXEMUL_FB_KEY_F3 0x524f5b1bL |
#define GXEMUL_FB_KEY_F4 0x534f5b1bL |
#define GXEMUL_FB_KEY_F5 0x35315b1bL |
#define GXEMUL_FB_KEY_F6 0x37315b1bL |
#define GXEMUL_FB_KEY_F7 0x38315b1bL |
#define GXEMUL_FB_KEY_F8 0x39315b1bL |
#define GXEMUL_FB_KEY_F9 0x38325b1bL |
#define GXEMUL_FB_KEY_F10 0x39325b1bL |
#define GXEMUL_FB_KEY_F11 0x33325b1bL |
#define GXEMUL_FB_KEY_F12 0x34325b1bL |
/** Function keys start code (F1=0x101) */ |
#define FUNCTION_KEYS 0x100 |
static irq_cmd_t gxemul_cmds[] = { |
{ |
CMD_MEM_READ_1, |
(void *) 0, |
0, |
2 |
} |
}; |
static irq_code_t gxemul_kbd = { |
1, |
gxemul_cmds |
}; |
/** Framebuffer switched on. */ |
static bool fb; |
/* |
// Please preserve this code (it can be used to determine scancodes) |
int to_hex(int v) |
{ |
return "0123456789ABCDEF"[v]; |
} |
*/ |
/** Process data sent when a key is pressed (in no-framebuffer mode). |
* |
* @param keybuffer Buffer of pressed key. |
* @param scan_code Scan code. |
* |
* @return Always 1. |
*/ |
static int gxemul_kbd_process_no_fb(keybuffer_t *keybuffer, int scan_code) |
{ |
// holds at most 4 latest scan codes |
static unsigned long buf = 0; |
// number of scan codes in #buf |
static int count = 0; |
/* |
// Preserve for detecting scan codes. |
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
keybuffer_push(keybuffer, 'X'); |
keybuffer_push(keybuffer, 'Y'); |
return 1; |
*/ |
if (scan_code == '\r') { |
scan_code = '\n'; |
} |
if (scan_code == GXEMUL_KEY_F5_F12_START_CODE) { |
switch (buf) { |
case GXEMUL_KEY_F5: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 5); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F6: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 6); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F7: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 7); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F8: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 8); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F9: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 9); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F10: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 10); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F11: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 11); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F12: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 12); |
buf = count = 0; |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
keybuffer_push(keybuffer, scan_code); |
buf = count = 0; |
return 1; |
} |
} |
// add to buffer |
buf |= ((unsigned long) scan_code) << (8 * (count++)); |
if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) { |
keybuffer_push(keybuffer, buf); |
buf = count = 0; |
return 1; |
} |
if (count <= 1) { |
return 1; |
} |
if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff) |
&& (buf & 0xffff) != (GXEMUL_KEY_F5 & 0xffff) ) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 2) { |
return 1; |
} |
switch (buf) { |
case GXEMUL_KEY_F1: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 1); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F2: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 2); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F3: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 3); |
buf = count = 0; |
return 1; |
case GXEMUL_KEY_F4: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 4); |
buf = count = 0; |
return 1; |
} |
if ((buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff) |
&& (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 3) { |
return 1; |
} |
switch (buf) { |
case GXEMUL_KEY_F5: |
case GXEMUL_KEY_F6: |
case GXEMUL_KEY_F7: |
case GXEMUL_KEY_F8: |
case GXEMUL_KEY_F9: |
case GXEMUL_KEY_F10: |
case GXEMUL_KEY_F11: |
case GXEMUL_KEY_F12: |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
buf = count = 0; |
return 1; |
} |
return 1; |
} |
/** Process data sent when a key is pressed (in framebuffer mode). |
* |
* @param keybuffer Buffer of pressed keys. |
* @param scan_code Scan code. |
* |
* @return Always 1. |
*/ |
static int gxemul_kbd_process_fb(keybuffer_t *keybuffer, int scan_code) |
{ |
// holds at most 4 latest scan codes |
static unsigned long buf = 0; |
// number of scan codes in #buf |
static int count = 0; |
/* |
// Please preserve this code (it can be used to determine scancodes) |
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
keybuffer_push(keybuffer, ' '); |
keybuffer_push(keybuffer, ' '); |
return 1; |
*/ |
if (scan_code == '\r') { |
scan_code = '\n'; |
} |
// add to buffer |
buf |= ((unsigned long) scan_code) << (8*(count++)); |
if ((buf & 0xff) != (GXEMUL_FB_KEY_F1 & 0xff)) { |
keybuffer_push(keybuffer, buf); |
buf = count = 0; |
return 1; |
} |
if (count <= 1) { |
return 1; |
} |
if ((buf & 0xffff) != (GXEMUL_FB_KEY_F1 & 0xffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 2) { |
return 1; |
} |
if ((buf & 0xffffff) != (GXEMUL_FB_KEY_F1 & 0xffffff) |
&& (buf & 0xffffff) != (GXEMUL_FB_KEY_F5 & 0xffffff) |
&& (buf & 0xffffff) != (GXEMUL_FB_KEY_F9 & 0xffffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 3) { |
return 1; |
} |
switch (buf) { |
case GXEMUL_FB_KEY_F1: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 1 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F2: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 2 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F3: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 3 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F4: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 4 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F5: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 5 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F6: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 6 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F7: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 7 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F8: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 8 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F9: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 9 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F10: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 10 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F11: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 11 ); |
buf = count = 0; |
return 1; |
case GXEMUL_FB_KEY_F12: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 12 ); |
buf = count = 0; |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff ); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
keybuffer_push(keybuffer, (buf >> 24) & 0xff); |
buf = count = 0; |
return 1; |
} |
return 1; |
} |
/** Initializes keyboard handler. */ |
int kbd_arch_init(void) |
{ |
fb = (sysinfo_value("fb.kind") == 1); |
gxemul_cmds[0].addr = (void *) sysinfo_value("kbd.address.virtual"); |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &gxemul_kbd); |
return 0; |
} |
/** Process data sent when a key is pressed. |
* |
* @param keybuffer Buffer of pressed keys. |
* @param call IPC call. |
* |
* @return Always 1. |
*/ |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
int scan_code = IPC_GET_ARG2(*call); |
if (fb) { |
return gxemul_kbd_process_fb(keybuffer, scan_code); |
} else { |
return gxemul_kbd_process_no_fb(keybuffer, scan_code); |
} |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ia64/include/kbd.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdia64 ia64 |
* @brief HelenOS ia64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_ia64_KBD_H_ |
#define KBD_ia64_KBD_H_ |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ia64/src/kbd.c |
---|
0,0 → 1,164 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdia64 ia64 |
* @brief HelenOS ia64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
#define KEY_F1 0x504f1b |
#define KEY_F2 0x514f1b |
#define KEY_F3 0x524f1b |
#define KEY_F4 0x534f1b |
#define KEY_F5 0x7e35315b1b |
#define KEY_F6 0x7e37315b1b |
#define KEY_F7 0x7e38315b1b |
#define KEY_F8 0x7e39315b1b |
#define KEY_F9 0x7e30325b1b |
#define KEY_F10 0x7e31325b1b |
#define KEY_F11 0x7e33325b1b |
#define KEY_F12 0x7e34325b1b |
#define FUNCTION_KEYS 0x100 |
irq_cmd_t ski_cmds[1] = { |
{ CMD_IA64_GETCHAR, 0, 0, 2 } |
}; |
irq_code_t ski_kbd = { |
1, |
ski_cmds |
}; |
int kbd_arch_init(void) |
{ |
if (sysinfo_value("kbd")) { |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &ski_kbd); |
return 0; |
} |
return 1; |
} |
/* |
* Please preserve this code (it can be used to determine scancodes) |
* |
int to_hex(int v) |
{ |
return "0123456789ABCDEF"[v]; |
} |
*/ |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
static unsigned long long buf = 0; |
static int count = 0; |
static int esc_count = 0; |
int scan_code = IPC_GET_ARG2(*call); |
/* |
* Please preserve this code (it can be used to determine scancodes) |
*/ |
//keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
//keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
//keybuffer_push(keybuffer, ' '); |
//keybuffer_push(keybuffer, ' '); |
//*/ |
if (scan_code) { |
buf |= (unsigned long long) scan_code<<(8*(count++)); |
} else { |
if (buf == 0x1b) { |
esc_count++; |
if (esc_count == 3) { |
__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); |
} |
} else { |
esc_count = 0; |
} |
if (!(buf & 0xff00)) { |
keybuffer_push(keybuffer, buf); |
} else { |
switch (buf) { |
case KEY_F1: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 1); |
break; |
case KEY_F2: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 2); |
break; |
case KEY_F3: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 3); |
break; |
case KEY_F4: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 4); |
break; |
case KEY_F5: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 5); |
break; |
case KEY_F6: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 6); |
break; |
case KEY_F7: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 7); |
break; |
case KEY_F8: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 8); |
break; |
case KEY_F9: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 9); |
break; |
case KEY_F10: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 10); |
break; |
case KEY_F11: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 11); |
break; |
case KEY_F12: |
keybuffer_push(keybuffer, FUNCTION_KEYS | 12); |
break; |
} |
} |
buf = count = 0; |
} |
return 1; |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ppc32/include/kbd.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdppc32 ppc32 |
* @brief HelenOS ppc32 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_ppc32_KBD_H_ |
#define KBD_ppc32_KBD_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ppc32/src/kbd.c |
---|
0,0 → 1,209 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdppc32 ppc32 |
* @brief HelenOS ppc32 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
irq_cmd_t cuda_cmds[1] = { |
{ CMD_PPC32_GETCHAR, 0, 0, 2 } |
}; |
irq_code_t cuda_kbd = { |
1, |
cuda_cmds |
}; |
#define SPECIAL 255 |
#define FUNCTION_KEYS 0x100 |
static int lchars[0x80] = { |
'a', |
's', |
'd', |
'f', |
'h', |
'g', |
'z', |
'x', |
'c', |
'v', |
SPECIAL, |
'b', |
'q', |
'w', |
'e', |
'r', |
'y', |
't', |
'1', |
'2', |
'3', |
'4', |
'6', |
'5', |
'=', |
'9', |
'7', |
'-', |
'8', |
'0', |
']', |
'o', |
'u', |
'[', |
'i', |
'p', |
'\n', /* Enter */ |
'l', |
'j', |
'\'', |
'k', |
';', |
'\\', |
',', |
'/', |
'n', |
'm', |
'.', |
'\t', /* Tab */ |
' ', |
'`', |
'\b', /* Backspace */ |
SPECIAL, |
SPECIAL, /* Escape */ |
SPECIAL, /* Ctrl */ |
SPECIAL, /* Alt */ |
SPECIAL, /* Shift */ |
SPECIAL, /* Caps-Lock */ |
SPECIAL, /* RAlt */ |
SPECIAL, /* Left */ |
SPECIAL, /* Right */ |
SPECIAL, /* Down */ |
SPECIAL, /* Up */ |
SPECIAL, |
SPECIAL, |
'.', /* Keypad . */ |
SPECIAL, |
'*', /* Keypad * */ |
SPECIAL, |
'+', /* Keypad + */ |
SPECIAL, |
SPECIAL, /* NumLock */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
'/', /* Keypad / */ |
'\n', /* Keypad Enter */ |
SPECIAL, |
'-', /* Keypad - */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
'0', /* Keypad 0 */ |
'1', /* Keypad 1 */ |
'2', /* Keypad 2 */ |
'3', /* Keypad 3 */ |
'4', /* Keypad 4 */ |
'5', /* Keypad 5 */ |
'6', /* Keypad 6 */ |
'7', /* Keypad 7 */ |
SPECIAL, |
'8', /* Keypad 8 */ |
'9', /* Keypad 9 */ |
SPECIAL, |
SPECIAL, |
SPECIAL, |
(FUNCTION_KEYS | 5), /* F5 */ |
(FUNCTION_KEYS | 6), /* F6 */ |
(FUNCTION_KEYS | 7), /* F7 */ |
(FUNCTION_KEYS | 3), /* F3 */ |
(FUNCTION_KEYS | 8), /* F8 */ |
(FUNCTION_KEYS | 9), /* F9 */ |
SPECIAL, |
(FUNCTION_KEYS | 11), /* F11 */ |
SPECIAL, |
(FUNCTION_KEYS | 13), /* F13 */ |
SPECIAL, |
SPECIAL, /* ScrollLock */ |
SPECIAL, |
(FUNCTION_KEYS | 10), /* F10 */ |
SPECIAL, |
(FUNCTION_KEYS | 12), /* F12 */ |
SPECIAL, |
SPECIAL, /* Pause */ |
SPECIAL, /* Insert */ |
SPECIAL, /* Home */ |
SPECIAL, /* PageUp */ |
SPECIAL, /* Delete */ |
(FUNCTION_KEYS | 4), /* F4 */ |
SPECIAL, /* End */ |
(FUNCTION_KEYS | 2), /* F2 */ |
SPECIAL, /* PageDown */ |
(FUNCTION_KEYS | 1) /* F1 */ |
}; |
int kbd_arch_init(void) |
{ |
return ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &cuda_kbd); |
} |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
int param = IPC_GET_ARG2(*call); |
if (param != -1) { |
uint8_t scancode = (uint8_t) param; |
if ((scancode & 0x80) != 0x80) { |
int key = lchars[scancode & 0x7f]; |
if (key != SPECIAL) |
keybuffer_push(keybuffer, key); |
} |
} |
return 1; |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ppc64/include/kbd.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdppc64 ppc64 |
* @brief HelenOS ppc64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_ppc64_KBD_H_ |
#define KBD_ppc64_KBD_H_ |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/ppc64/src/kbd.c |
---|
0,0 → 1,56 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdppc64 ppc64 |
* @brief HelenOS ppc64 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
int kbd_arch_init(void) |
{ |
return 0; |
} |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
return 1; |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/mips32/include/kbd.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdmips32 mips32 |
* @brief HelenOS mips32 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_mips32_KBD_H_ |
#define KBD_mips32_KBD_H_ |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/mips32/src/kbd.c |
---|
0,0 → 1,377 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbdmips32 mips32 |
* @brief HelenOS mips32 arch dependent parts of uspace keyboard handler. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <arch/kbd.h> |
#include <ipc/ipc.h> |
#include <sysinfo.h> |
#include <kbd.h> |
#include <keys.h> |
#define MSIM_KEY_F1 0x504f1bL |
#define MSIM_KEY_F2 0x514f1bL |
#define MSIM_KEY_F3 0x524f1bL |
#define MSIM_KEY_F4 0x534f1bL |
#define MSIM_KEY_F5 0x35315b1bL |
#define MSIM_KEY_F6 0x37315b1bL |
#define MSIM_KEY_F7 0x38315b1bL |
#define MSIM_KEY_F8 0x39315b1bL |
#define MSIM_KEY_F9 0x30325b1bL |
#define MSIM_KEY_F10 0x31325b1bL |
#define MSIM_KEY_F11 0x33325b1bL |
#define MSIM_KEY_F12 0x34325b1bL |
#define GXEMUL_KEY_F1 0x504f5b1bL |
#define GXEMUL_KEY_F2 0x514f5b1bL |
#define GXEMUL_KEY_F3 0x524f5b1bL |
#define GXEMUL_KEY_F4 0x534f5b1bL |
#define GXEMUL_KEY_F5 0x35315b1bL |
#define GXEMUL_KEY_F6 0x37315b1bL |
#define GXEMUL_KEY_F7 0x38315b1bL |
#define GXEMUL_KEY_F8 0x39315b1bL |
#define GXEMUL_KEY_F9 0x38325b1bL |
#define GXEMUL_KEY_F10 0x39325b1bL |
#define GXEMUL_KEY_F11 0x33325b1bL |
#define GXEMUL_KEY_F12 0x34325b1bL |
#define FUNCTION_KEYS 0x100 |
irq_cmd_t msim_cmds[1] = { |
{ CMD_MEM_READ_1, (void *) 0, 0, 2 } |
}; |
irq_code_t msim_kbd = { |
1, |
msim_cmds |
}; |
static int msim,gxemul; |
static int fb_fb; |
int kbd_arch_init(void) |
{ |
fb_fb = (sysinfo_value("fb.kind") == 1); |
msim_cmds[0].addr = sysinfo_value("kbd.address.virtual"); |
ipc_register_irq(sysinfo_value("kbd.inr"), sysinfo_value("kbd.devno"), 0, &msim_kbd); |
return 0; |
} |
/* |
//* |
//* Please preserve this code (it can be used to determine scancodes) |
//* |
int to_hex(int v) |
{ |
return "0123456789ABCDEF"[v]; |
} |
*/ |
static int kbd_arch_process_no_fb(keybuffer_t *keybuffer, int scan_code) |
{ |
static unsigned long buf = 0; |
static int count = 0; |
/* Please preserve this code (it can be used to determine scancodes) |
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
keybuffer_push(keybuffer, ' '); |
keybuffer_push(keybuffer, ' '); |
return 1; |
*/ |
if(scan_code == 0x7e) { |
switch (buf) { |
case MSIM_KEY_F5: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 5); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F6: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 6); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F7: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 7); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F8: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 8); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F9: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 9); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F10: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 10); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F11: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 11); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F12: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 12); |
buf = count = 0; |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
keybuffer_push(keybuffer, (buf >> 16) &0xff); |
keybuffer_push(keybuffer, (buf >> 24) &0xff); |
keybuffer_push(keybuffer, scan_code); |
buf = count = 0; |
return 1; |
} |
} |
buf |= ((unsigned long) scan_code)<<(8*(count++)); |
if((buf & 0xff) != (MSIM_KEY_F1 & 0xff)) { |
keybuffer_push(keybuffer, buf); |
buf = count = 0; |
return 1; |
} |
if (count <= 1) |
return 1; |
if ((buf & 0xffff) != (MSIM_KEY_F1 & 0xffff) |
&& (buf & 0xffff) != (MSIM_KEY_F5 & 0xffff) ) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 2) |
return 1; |
switch (buf) { |
case MSIM_KEY_F1: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 1); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F2: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 2); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F3: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 3); |
buf = count = 0; |
return 1; |
case MSIM_KEY_F4: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 4); |
buf = count = 0; |
return 1; |
} |
if((buf & 0xffffff) != (MSIM_KEY_F5 & 0xffffff) |
&& (buf & 0xffffff) != (MSIM_KEY_F9 & 0xffffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
buf=count=0; |
return 1; |
} |
if (count <= 3) |
return 1; |
switch (buf) { |
case MSIM_KEY_F5: |
case MSIM_KEY_F6: |
case MSIM_KEY_F7: |
case MSIM_KEY_F8: |
case MSIM_KEY_F9: |
case MSIM_KEY_F10: |
case MSIM_KEY_F11: |
case MSIM_KEY_F12: |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
keybuffer_push(keybuffer, (buf >> 16) &0xff); |
keybuffer_push(keybuffer, (buf >> 24) &0xff); |
buf = count = 0; |
return 1; |
} |
return 1; |
} |
static int kbd_arch_process_fb(keybuffer_t *keybuffer, int scan_code) |
{ |
static unsigned long buf = 0; |
static int count = 0; |
/* Please preserve this code (it can be used to determine scancodes) |
keybuffer_push(keybuffer, to_hex((scan_code>>4)&0xf)); |
keybuffer_push(keybuffer, to_hex(scan_code&0xf)); |
keybuffer_push(keybuffer, ' '); |
keybuffer_push(keybuffer, ' '); |
return 1; |
*/ |
if (scan_code == '\r') |
scan_code = '\n'; |
buf |= ((unsigned long) scan_code)<<(8*(count++)); |
if ((buf & 0xff) != (GXEMUL_KEY_F1 & 0xff)) { |
keybuffer_push(keybuffer, buf); |
buf = count = 0; |
return 1; |
} |
if (count <= 1) |
return 1; |
if ((buf & 0xffff) != (GXEMUL_KEY_F1 & 0xffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) &0xff); |
buf = count = 0; |
return 1; |
} |
if (count <= 2) |
return 1; |
if ((buf & 0xffffff) != (GXEMUL_KEY_F1 & 0xffffff) |
&& (buf & 0xffffff) != (GXEMUL_KEY_F5 & 0xffffff) |
&& (buf & 0xffffff) != (GXEMUL_KEY_F9 & 0xffffff)) { |
keybuffer_push(keybuffer, buf & 0xff); |
keybuffer_push(keybuffer, (buf >> 8) & 0xff); |
keybuffer_push(keybuffer, (buf >> 16) & 0xff); |
buf = count = 0; |
return 1; |
} |
if ( count <= 3 ) |
return 1; |
switch (buf) { |
case GXEMUL_KEY_F1: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 1 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F2: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 2 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F3: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 3 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F4: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 4 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F5: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 5 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F6: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 6 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F7: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 7 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F8: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 8 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F9: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 9 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F10: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 10 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F11: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 11 ); |
buf=count=0; |
return 1; |
case GXEMUL_KEY_F12: |
keybuffer_push(keybuffer,FUNCTION_KEYS | 12 ); |
buf=count=0; |
return 1; |
default: |
keybuffer_push(keybuffer, buf & 0xff ); |
keybuffer_push(keybuffer, (buf >> 8) &0xff ); |
keybuffer_push(keybuffer, (buf >> 16) &0xff ); |
keybuffer_push(keybuffer, (buf >> 24) &0xff ); |
buf=count=0; |
return 1; |
} |
return 1; |
} |
int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call) |
{ |
int scan_code = IPC_GET_ARG2(*call); |
static int esc_count=0; |
if (scan_code == 0x1b) { |
esc_count++; |
if (esc_count == 3) |
__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); |
} else { |
esc_count=0; |
} |
if (fb_fb) |
return kbd_arch_process_fb(keybuffer, scan_code); |
return kbd_arch_process_no_fb(keybuffer, scan_code); |
} |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/arch/amd64 |
---|
0,0 → 1,0 |
link ia32 |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/uspace/srv/kbd/arch/mips32eb |
---|
0,0 → 1,0 |
link mips32 |
Property changes: |
Added: svn:special |
+* |
\ No newline at end of property |
/branches/dd/uspace/srv/kbd/include/layout.h |
---|
File deleted |
/branches/dd/uspace/srv/kbd/include/kbd_port.h |
---|
File deleted |
/branches/dd/uspace/srv/kbd/include/kbd_ctl.h |
---|
File deleted |
/branches/dd/uspace/srv/kbd/include/key_buffer.h |
---|
38,25 → 38,23 |
#define __KEY_BUFFER_H__ |
#include <sys/types.h> |
#include <kbd/kbd.h> |
/** Size of buffer for pressed keys */ |
#define KEYBUFFER_SIZE 128 |
typedef struct { |
kbd_event_t fifo[KEYBUFFER_SIZE]; |
int fifo[KEYBUFFER_SIZE]; |
unsigned long head; |
unsigned long tail; |
unsigned long items; |
} keybuffer_t; |
extern void keybuffer_free(keybuffer_t *); |
extern void keybuffer_init(keybuffer_t *); |
extern int keybuffer_available(keybuffer_t *); |
extern int keybuffer_empty(keybuffer_t *); |
extern void keybuffer_push(keybuffer_t *, const kbd_event_t *); |
extern void keybuffer_push0(keybuffer_t *, int c); |
extern int keybuffer_pop(keybuffer_t *, kbd_event_t *); |
void keybuffer_free(keybuffer_t *keybuffer); |
void keybuffer_init(keybuffer_t *keybuffer); |
int keybuffer_available(keybuffer_t *keybuffer); |
int keybuffer_empty(keybuffer_t *keybuffer); |
void keybuffer_push(keybuffer_t *keybuffer, int key); |
int keybuffer_pop(keybuffer_t *keybuffer, int *c); |
#endif |
/branches/dd/uspace/srv/kbd/include/keys.h |
---|
0,0 → 1,62 |
/* |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** |
* @addtogroup kbdgen |
* @{ |
*/ |
/** |
* @file |
*/ |
#ifndef _KBD_KEYS_H_ |
#define _KBD_KEYS_H_ |
#define KBD_PUSHCHAR 1024 |
#define KBD_MS_LEFT 1025 |
#define KBD_MS_RIGHT 1026 |
#define KBD_MS_MIDDLE 1027 |
#define KBD_MS_MOVE 1028 |
#define KBD_KEY_F1 0x3b |
#define KBD_KEY_F2 0x3c |
#define KBD_KEY_F3 0x3d |
#define KBD_KEY_F4 0x3e |
#define KBD_KEY_F5 0x3f |
#define KBD_KEY_F6 0x40 |
#define KBD_KEY_F7 0x41 |
#define KBD_KEY_F8 0x42 |
#define KBD_KEY_F9 0x43 |
#define KBD_KEY_F10 0x44 |
#define KBD_KEY_F11 0x45 |
#define KBD_KEY_F12 0x46 |
#endif |
/** @} |
*/ |
/branches/dd/uspace/srv/kbd/include/kbd.h |
---|
39,18 → 39,10 |
#include <key_buffer.h> |
#define KBD_EVENT 1024 |
#define KBD_MS_LEFT 1025 |
#define KBD_MS_RIGHT 1026 |
#define KBD_MS_MIDDLE 1027 |
#define KBD_MS_MOVE 1028 |
extern int kbd_arch_init(void); |
extern int kbd_arch_process(keybuffer_t *keybuffer, ipc_call_t *call); |
extern int mouse_arch_process(int phoneid, ipc_call_t *call); |
extern int cir_service; |
extern int cir_phone; |
extern void kbd_push_scancode(int); |
extern void kbd_push_ev(int, unsigned int); |
#endif |
/** |
/branches/dd/uspace/srv/kbd/Makefile |
---|
31,9 → 31,9 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
include ../../../Makefile.config |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -Iinclude -I../libadt/include |
LIBS = $(LIBC_PREFIX)/libc.a |
46,105 → 46,65 |
generic/kbd.c \ |
generic/key_buffer.c |
ARCH_SOURCES = |
GENARCH_SOURCES = |
ARCH_SOURCES = \ |
arch/$(ARCH)/src/kbd.c |
ifeq ($(KBD_LAYOUT), us_qwerty) |
GENARCH_SOURCES += layout/us_qwerty.c |
ifeq ($(ARCH), ia32) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/mouse.c \ |
arch/$(ARCH)/src/scanc.c |
GENARCH_SOURCES = \ |
genarch/src/kbd.c |
CFLAGS += -DMOUSE_ENABLED |
endif |
ifeq ($(KBD_LAYOUT), us_dvorak) |
GENARCH_SOURCES += layout/us_dvorak.c |
ifeq ($(ARCH), amd64) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/mouse.c \ |
arch/$(ARCH)/src/scanc.c |
GENARCH_SOURCES = \ |
genarch/src/kbd.c |
CFLAGS += -DMOUSE_ENABLED |
endif |
ifeq ($(UARCH), amd64) |
GENARCH_SOURCES += \ |
port/i8042.c \ |
ctl/pc.c |
ifeq ($(ARCH), sparc64) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/scanc.c |
GENARCH_SOURCES = \ |
genarch/src/kbd.c |
endif |
ifeq ($(UARCH), arm32) |
GENARCH_SOURCES += \ |
port/gxemul.c |
ifeq ($(CONFIG_FB), y) |
GENARCH_SOURCES += \ |
ctl/gxe_fb.c |
else |
GENARCH_SOURCES += \ |
ctl/stty.c |
endif |
ifeq ($(ARCH), arm32) |
ifeq ($(MACHINE), gxemul_testarm) |
ARCH_SOURCES += \ |
arch/$(ARCH)/src/kbd_gxemul.c |
endif |
ifeq ($(UARCH), ia32) |
GENARCH_SOURCES += \ |
port/i8042.c \ |
ctl/pc.c |
endif |
ifeq ($(MACHINE), i640GX) |
GENARCH_SOURCES += \ |
port/i8042.c \ |
ctl/pc.c |
endif |
ifeq ($(MACHINE), ski) |
GENARCH_SOURCES += \ |
port/ski.c \ |
ctl/stty.c |
endif |
ifeq ($(MACHINE), msim) |
GENARCH_SOURCES += \ |
port/msim.c \ |
ctl/stty.c |
endif |
ifeq ($(MACHINE), lgxemul) |
GENARCH_SOURCES += \ |
port/gxemul.c |
ifeq ($(CONFIG_FB), y) |
GENARCH_SOURCES += \ |
ctl/gxe_fb.c |
else |
GENARCH_SOURCES += \ |
ctl/stty.c |
endif |
endif |
ifeq ($(MACHINE), bgxemul) |
GENARCH_SOURCES += \ |
port/gxemul.c \ |
ctl/stty.c |
endif |
ifeq ($(UARCH), ppc32) |
GENARCH_SOURCES += \ |
port/dummy.c \ |
ctl/stty.c |
endif |
ifeq ($(UARCH), sparc64) |
GENARCH_SOURCES += \ |
port/z8530.c \ |
ctl/sun.c |
endif |
GENERIC_OBJECTS := $(addsuffix .o,$(basename $(GENERIC_SOURCES))) |
ARCH_OBJECTS := $(addsuffix .o,$(basename $(ARCH_SOURCES))) |
GENARCH_OBJECTS := $(addsuffix .o,$(basename $(GENARCH_SOURCES))) |
OBJECTS := $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS) |
.PHONY: all clean depend disasm links |
all: $(OUTPUT) $(OUTPUT).disasm |
all: links $(OUTPUT) disasm |
-include Makefile.depend |
links: |
ln -sfn ../arch/$(ARCH)/include include/arch |
ln -sfn ../genarch/include include/genarch |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend include/arch include/genarch |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(OUTPUT): $(ARCH_OBJECTS) $(GENERIC_OBJECTS) $(GENARCH_OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld -e __entry_driver $(GENERIC_OBJECTS) $(ARCH_OBJECTS) $(GENARCH_OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/srv/kbd/genarch/include/kbd.h |
---|
0,0 → 1,47 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_genarch_KBD_H_ |
#define KBD_genarch_KBD_H_ |
#include <key_buffer.h> |
extern void key_released(keybuffer_t *keybuffer, unsigned char key); |
extern void key_pressed(keybuffer_t *keybuffer, unsigned char key); |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/genarch/include/scanc.h |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#ifndef KBD_SCANC_H_ |
#define KBD_SCANC_H_ |
#define FUNCTION_KEYS 0x100 |
#define SPECIAL 255 |
extern int sc_primary_map[]; |
extern int sc_secondary_map[]; |
#endif |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/kbd/genarch/src/kbd.c |
---|
0,0 → 1,113 |
/* |
* Copyright (c) 2001-2004 Jakub Jermar |
* Copyright (c) 2006 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup kbd |
* @brief Handling of keyboard IRQ notifications for several architectures. |
* @ingroup kbd |
* @{ |
*/ |
/** @file |
*/ |
#include <key_buffer.h> |
#include <arch/scanc.h> |
#include <genarch/scanc.h> |
#include <genarch/kbd.h> |
#include <libc.h> |
#define PRESSED_SHIFT (1<<0) |
#define PRESSED_CAPSLOCK (1<<1) |
#define LOCKED_CAPSLOCK (1<<0) |
static volatile int keyflags; /**< Tracking of multiple keypresses. */ |
static volatile int lockflags; /**< Tracking of multiple keys lockings. */ |
void key_released(keybuffer_t *keybuffer, unsigned char key) |
{ |
switch (key) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags &= ~PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags &= ~PRESSED_CAPSLOCK; |
if (lockflags & LOCKED_CAPSLOCK) |
lockflags &= ~LOCKED_CAPSLOCK; |
else |
lockflags |= LOCKED_CAPSLOCK; |
break; |
default: |
break; |
} |
} |
void key_pressed(keybuffer_t *keybuffer, unsigned char key) |
{ |
int *map = sc_primary_map; |
int ascii = sc_primary_map[key]; |
int shift, capslock; |
int letter = 0; |
static int esc_count = 0; |
if (key == SC_ESC) { |
esc_count++; |
if (esc_count == 3) |
__SYSCALL0(SYS_DEBUG_ENABLE_CONSOLE); |
} else { |
esc_count = 0; |
} |
switch (key) { |
case SC_LSHIFT: |
case SC_RSHIFT: |
keyflags |= PRESSED_SHIFT; |
break; |
case SC_CAPSLOCK: |
keyflags |= PRESSED_CAPSLOCK; |
break; |
case SC_SPEC_ESCAPE: |
break; |
default: |
letter = ((ascii >= 'a') && (ascii <= 'z')); |
capslock = (keyflags & PRESSED_CAPSLOCK) || (lockflags & LOCKED_CAPSLOCK); |
shift = keyflags & PRESSED_SHIFT; |
if (letter && capslock) |
shift = !shift; |
if (shift) |
map = sc_secondary_map; |
if (map[key] != SPECIAL) |
keybuffer_push(keybuffer, map[key]); |
break; |
} |
} |
/** |
* @} |
*/ |
/branches/dd/uspace/srv/pci/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
53,7 → 52,7 |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
$(MAKE) -C libpci clean |
depend: |
61,7 → 60,7 |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(MAKE) -C libpci |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
/branches/dd/uspace/srv/pci/update-ids |
---|
2,14 → 2,15 |
wget http://pciids.sourceforge.net/v2.2/pci.ids |
cat > pci_ids.h <<EOF |
cat >pci_ids.h <<EOF |
/* DO NOT EDIT, THIS FILE IS AUTOMATICALLY GENERATED */ |
char *pci_ids[] = { |
EOF |
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | sed -n 's/\(.*\)/"\1",/p' >> pci_ids.h |
cat pci.ids | grep -v '^#.*' | grep -v '^$' | tr \" \' | sed -n 's/\(.*\)/"\1",/p' >>pci_ids.h |
cat >> pci_ids.h <<EOF |
cat >>pci_ids.h <<EOF |
"" |
}; |
EOF |
/branches/dd/uspace/app/trace/proto.h |
---|
File deleted |
/branches/dd/uspace/app/trace/ipc_desc.c |
---|
File deleted |
/branches/dd/uspace/app/trace/ipcp.c |
---|
File deleted |
/branches/dd/uspace/app/trace/errors.c |
---|
File deleted |
/branches/dd/uspace/app/trace/Makefile |
---|
File deleted |
/branches/dd/uspace/app/trace/syscalls.c |
---|
File deleted |
/branches/dd/uspace/app/trace/trace.c |
---|
File deleted |
/branches/dd/uspace/app/trace/ipc_desc.h |
---|
File deleted |
/branches/dd/uspace/app/trace/ipcp.h |
---|
File deleted |
/branches/dd/uspace/app/trace/errors.h |
---|
File deleted |
/branches/dd/uspace/app/trace/syscalls.h |
---|
File deleted |
/branches/dd/uspace/app/trace/proto.c |
---|
File deleted |
/branches/dd/uspace/app/trace/trace.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/util.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/TODO |
---|
File deleted |
/branches/dd/uspace/app/bdsh/exec.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/errstr.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/exec.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/scli.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/Makefile |
---|
File deleted |
/branches/dd/uspace/app/bdsh/scli.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/input.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/LICENSE |
---|
File deleted |
/branches/dd/uspace/app/bdsh/input.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/AUTHORS |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/cmds.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtin_cmds.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/mknewcmd |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/uspace/app/bdsh/cmds/mod_cmds.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/module_aliases.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/README |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/modules.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/ls.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/ls/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/rm.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/rm_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/rm/rm.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/cp.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/cp_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cp/cp.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/touch/touch.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/mkdir.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/mkdir/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/cat/cat_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/sleep/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/sleep/sleep.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/sleep/sleep_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/sleep/sleep.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/help/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/help/help_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/pwd_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/pwd.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/modules/pwd/pwd.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/builtins.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/cd/cd.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/entry.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit_def.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/exit/exit.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/README |
---|
File deleted |
/branches/dd/uspace/app/bdsh/cmds/builtins/builtin_aliases.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/config.h |
---|
File deleted |
/branches/dd/uspace/app/bdsh/errors.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/README |
---|
File deleted |
/branches/dd/uspace/app/bdsh/util.c |
---|
File deleted |
/branches/dd/uspace/app/bdsh/errors.h |
---|
File deleted |
/branches/dd/uspace/app/tester/loop/loop1.c |
---|
File deleted |
/branches/dd/uspace/app/tester/loop/loop1.def |
---|
File deleted |
/branches/dd/uspace/app/tester/stdio/stdio1.def |
---|
File deleted |
/branches/dd/uspace/app/tester/stdio/stdio2.def |
---|
File deleted |
/branches/dd/uspace/app/tester/stdio/stdio1.c |
---|
File deleted |
/branches/dd/uspace/app/tester/stdio/stdio2.c |
---|
File deleted |
/branches/dd/uspace/app/tester/console/console1.def |
---|
File deleted |
/branches/dd/uspace/app/tester/console/console1.c |
---|
File deleted |
/branches/dd/uspace/app/tester/vfs/vfs1.c |
---|
45,7 → 45,7 |
{ |
int rc; |
rc = mount("tmpfs", "/", "nulldev0", 0); |
rc = mount("tmpfs", "/", "nulldev0"); |
switch (rc) { |
case EOK: |
if (!quiet) |
/branches/dd/uspace/app/tester/tester.c |
---|
56,11 → 56,7 |
#include "ipc/answer.def" |
#include "ipc/hangup.def" |
#include "devmap/devmap1.def" |
#include "loop/loop1.def" |
#include "vfs/vfs1.def" |
#include "console/console1.def" |
#include "stdio/stdio1.def" |
#include "stdio/stdio2.def" |
{NULL, NULL, NULL} |
}; |
111,17 → 107,8 |
printf("*\t\t\tRun all safe tests\n"); |
} |
int main(int argc, char **argv) |
int main(void) |
{ |
printf("Number of arguments: %d\n", argc); |
if (argv) { |
printf("Arguments:"); |
while (*argv) { |
printf(" '%s'", *argv++); |
} |
printf("\n"); |
} |
while (1) { |
char c; |
test_t *test; |
137,22 → 124,15 |
if (c == 'a') |
break; |
if (test->name == NULL) |
if (c > 'a') |
printf("Unknown test\n\n"); |
else |
run_test(test); |
} else if (c == '*') { |
} else if (c == '*') |
run_safe_tests(); |
} else if (c < 0) { |
/* got EOF */ |
break; |
} else { |
else |
printf("Invalid test\n\n"); |
} |
} |
return 0; |
} |
/** @} |
/branches/dd/uspace/app/tester/ipc/send_sync.c |
---|
35,6 → 35,7 |
{ |
int phoneid; |
int res; |
static int msgid = 1; |
char c; |
printf("Select phoneid to send msg: 2-9 (q to skip)\n"); |
/branches/dd/uspace/app/tester/tester.h |
---|
69,11 → 69,7 |
extern char * test_answer(bool quiet); |
extern char * test_hangup(bool quiet); |
extern char * test_devmap1(bool quiet); |
extern char * test_loop1(bool quiet); |
extern char * test_vfs1(bool quiet); |
extern char * test_console1(bool quiet); |
extern char * test_stdio1(bool quiet); |
extern char * test_stdio2(bool quiet); |
extern test_t tests[]; |
/branches/dd/uspace/app/tester/devmap/devmap1.c |
---|
32,7 → 32,7 |
#include <ipc/services.h> |
#include <async.h> |
#include <errno.h> |
#include <ipc/devmap.h> |
#include <../../../srv/devmap/devmap.h> |
#include "../tester.h" |
#include <time.h> |
132,10 → 132,12 |
int phone; |
ipcarg_t callback_phonehash; |
phone = ipc_connect_me_to_blocking(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); |
if (phone < 0) { |
printf("Failed to connect to device mapper\n"); |
return -1; |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, DEVMAP_DRIVER, 0); |
while (phone < 0) { |
usleep(100000); |
phone = ipc_connect_me_to(PHONE_NS, SERVICE_DEVMAP, |
DEVMAP_DRIVER, 0); |
} |
req = async_send_2(phone, DEVMAP_DRIVER_REGISTER, 0, 0, &answer); |
/branches/dd/uspace/app/tester/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
53,11 → 52,7 |
ipc/send_sync.c \ |
ipc/answer.c \ |
ipc/hangup.c \ |
loop/loop1.c \ |
devmap/devmap1.c \ |
console/console1.c \ |
stdio/stdio1.c \ |
stdio/stdio2.c \ |
vfs/vfs1.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
64,24 → 59,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/ash/tools/mksyntax.c |
---|
0,0 → 1,428 |
/* $NetBSD: mksyntax.c,v 1.23 2000/07/18 19:13:21 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#ifndef lint |
static const char copyright[] = |
"@(#) Copyright (c) 1991, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"; |
#endif /* not lint */ |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)mksyntax.c 8.2 (Berkeley) 5/4/95"; |
#else |
static const char rcsid[] = |
"$NetBSD: mksyntax.c,v 1.23 2000/07/18 19:13:21 cgd Exp $"; |
#endif |
#endif /* not lint */ |
/* |
* This program creates syntax.h and syntax.c. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <sys/types.h> |
#include "../parser.h" |
struct synclass { |
char *name; |
char *comment; |
}; |
/* Syntax classes */ |
struct synclass synclass[] = { |
{ "CWORD", "character is nothing special" }, |
{ "CNL", "newline character" }, |
{ "CBACK", "a backslash character" }, |
{ "CSQUOTE", "single quote" }, |
{ "CDQUOTE", "double quote" }, |
{ "CENDQUOTE", "a terminating quote" }, |
{ "CBQUOTE", "backwards single quote" }, |
{ "CVAR", "a dollar sign" }, |
{ "CENDVAR", "a '}' character" }, |
{ "CLP", "a left paren in arithmetic" }, |
{ "CRP", "a right paren in arithmetic" }, |
{ "CEOF", "end of file" }, |
{ "CCTL", "like CWORD, except it must be escaped" }, |
{ "CSPCL", "these terminate a word" }, |
{ NULL, NULL } |
}; |
/* |
* Syntax classes for is_ functions. Warning: if you add new classes |
* you may have to change the definition of the is_in_name macro. |
*/ |
struct synclass is_entry[] = { |
{ "ISDIGIT", "a digit" }, |
{ "ISUPPER", "an upper case letter" }, |
{ "ISLOWER", "a lower case letter" }, |
{ "ISUNDER", "an underscore" }, |
{ "ISSPECL", "the name of a special parameter" }, |
{ NULL, NULL } |
}; |
static char writer[] = "\ |
/*\n\ |
* This file was generated by the mksyntax program.\n\ |
*/\n\ |
\n"; |
static FILE *cfile; |
static FILE *hfile; |
static char *syntax[513]; |
static int base; |
static int size; /* number of values which a char variable can have */ |
static int nbits; /* number of bits in a character */ |
static int digit_contig;/* true if digits are contiguous */ |
static void filltable(char *); |
static void init(void); |
static void add(char *, char *); |
static void print(char *); |
static void output_type_macros(void); |
static void digit_convert(void); |
int main(int, char **); |
int |
main(argc, argv) |
int argc; |
char **argv; |
{ |
#ifdef TARGET_CHAR |
TARGET_CHAR c; |
TARGET_CHAR d; |
#else |
char c; |
char d; |
#endif |
int sign; |
int i; |
char buf[80]; |
int pos; |
static char digit[] = "0123456789"; |
/* Create output files */ |
if ((cfile = fopen("syntax.c", "w")) == NULL) { |
perror("syntax.c"); |
exit(2); |
} |
if ((hfile = fopen("syntax.h", "w")) == NULL) { |
perror("syntax.h"); |
exit(2); |
} |
fputs(writer, hfile); |
fputs(writer, cfile); |
/* Determine the characteristics of chars. */ |
c = -1; |
if (c <= 0) |
sign = 1; |
else |
sign = 0; |
for (nbits = 1 ; ; nbits++) { |
d = (1 << nbits) - 1; |
if (d == c) |
break; |
} |
printf("%s %d bit chars\n", sign? "signed" : "unsigned", nbits); |
if (nbits > 9) { |
fputs("Characters can't have more than 9 bits\n", stderr); |
exit(2); |
} |
size = (1 << nbits) + 1; |
base = 1; |
if (sign) |
base += 1 << (nbits - 1); |
digit_contig = 1; |
for (i = 0 ; i < 10 ; i++) { |
if (digit[i] != '0' + i) |
digit_contig = 0; |
} |
fputs("#include <sys/cdefs.h>\n", hfile); |
fputs("#include <ctype.h>\n", hfile); |
/* Generate the #define statements in the header file */ |
fputs("/* Syntax classes */\n", hfile); |
for (i = 0 ; synclass[i].name ; i++) { |
sprintf(buf, "#define %s %d", synclass[i].name, i); |
fputs(buf, hfile); |
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) |
putc('\t', hfile); |
fprintf(hfile, "/* %s */\n", synclass[i].comment); |
} |
putc('\n', hfile); |
fputs("/* Syntax classes for is_ functions */\n", hfile); |
for (i = 0 ; is_entry[i].name ; i++) { |
sprintf(buf, "#define %s %#o", is_entry[i].name, 1 << i); |
fputs(buf, hfile); |
for (pos = strlen(buf) ; pos < 32 ; pos = (pos + 8) & ~07) |
putc('\t', hfile); |
fprintf(hfile, "/* %s */\n", is_entry[i].comment); |
} |
putc('\n', hfile); |
fprintf(hfile, "#define SYNBASE %d\n", base); |
fprintf(hfile, "#define PEOF %d\n\n", -base); |
if (sign) |
fprintf(hfile, "#define UPEOF %d\n\n", -base); |
else |
fprintf(hfile, "#define UPEOF ((unsigned char) %d)\n\n", -base); |
putc('\n', hfile); |
fputs("#define BASESYNTAX (basesyntax + SYNBASE)\n", hfile); |
fputs("#define DQSYNTAX (dqsyntax + SYNBASE)\n", hfile); |
fputs("#define SQSYNTAX (sqsyntax + SYNBASE)\n", hfile); |
fputs("#define ARISYNTAX (arisyntax + SYNBASE)\n", hfile); |
putc('\n', hfile); |
output_type_macros(); /* is_digit, etc. */ |
putc('\n', hfile); |
/* Generate the syntax tables. */ |
fputs("#include \"shell.h\"\n", cfile); |
fputs("#include \"syntax.h\"\n\n", cfile); |
init(); |
fputs("/* syntax table used when not in quotes */\n", cfile); |
add("\n", "CNL"); |
add("\\", "CBACK"); |
add("'", "CSQUOTE"); |
add("\"", "CDQUOTE"); |
add("`", "CBQUOTE"); |
add("$", "CVAR"); |
add("}", "CENDVAR"); |
add("<>();&| \t", "CSPCL"); |
print("basesyntax"); |
init(); |
fputs("\n/* syntax table used when in double quotes */\n", cfile); |
add("\n", "CNL"); |
add("\\", "CBACK"); |
add("\"", "CENDQUOTE"); |
add("`", "CBQUOTE"); |
add("$", "CVAR"); |
add("}", "CENDVAR"); |
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ |
add("!*?[=~:/-]", "CCTL"); |
print("dqsyntax"); |
init(); |
fputs("\n/* syntax table used when in single quotes */\n", cfile); |
add("\n", "CNL"); |
add("'", "CENDQUOTE"); |
/* ':/' for tilde expansion, '-' for [a\-x] pattern ranges */ |
add("!*?[=~:/-]\\", "CCTL"); |
print("sqsyntax"); |
init(); |
fputs("\n/* syntax table used when in arithmetic */\n", cfile); |
add("\n", "CNL"); |
add("\\", "CBACK"); |
add("`", "CBQUOTE"); |
add("'", "CSQUOTE"); |
add("\"", "CDQUOTE"); |
add("$", "CVAR"); |
add("}", "CENDVAR"); |
add("(", "CLP"); |
add(")", "CRP"); |
print("arisyntax"); |
filltable("0"); |
fputs("\n/* character classification table */\n", cfile); |
add("0123456789", "ISDIGIT"); |
add("abcdefghijklmnopqrstucvwxyz", "ISLOWER"); |
add("ABCDEFGHIJKLMNOPQRSTUCVWXYZ", "ISUPPER"); |
add("_", "ISUNDER"); |
add("#?$!-*@", "ISSPECL"); |
print("is_type"); |
if (! digit_contig) |
digit_convert(); |
exit(0); |
/* NOTREACHED */ |
} |
/* |
* Clear the syntax table. |
*/ |
static void |
filltable(dftval) |
char *dftval; |
{ |
int i; |
for (i = 0 ; i < size ; i++) |
syntax[i] = dftval; |
} |
/* |
* Initialize the syntax table with default values. |
*/ |
static void |
init() |
{ |
filltable("CWORD"); |
syntax[0] = "CEOF"; |
#ifdef TARGET_CHAR |
syntax[base + (TARGET_CHAR)CTLESC] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLVAR] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLENDVAR] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLBACKQ] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLBACKQ + (TARGET_CHAR)CTLQUOTE] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLARI] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLENDARI] = "CCTL"; |
syntax[base + (TARGET_CHAR)CTLQUOTEMARK] = "CCTL"; |
#else |
syntax[base + CTLESC] = "CCTL"; |
syntax[base + CTLVAR] = "CCTL"; |
syntax[base + CTLENDVAR] = "CCTL"; |
syntax[base + CTLBACKQ] = "CCTL"; |
syntax[base + CTLBACKQ + CTLQUOTE] = "CCTL"; |
syntax[base + CTLARI] = "CCTL"; |
syntax[base + CTLENDARI] = "CCTL"; |
syntax[base + CTLQUOTEMARK] = "CCTL"; |
#endif /* TARGET_CHAR */ |
} |
/* |
* Add entries to the syntax table. |
*/ |
static void |
add(p, type) |
char *p, *type; |
{ |
while (*p) |
syntax[*p++ + base] = type; |
} |
/* |
* Output the syntax table. |
*/ |
static void |
print(name) |
char *name; |
{ |
int i; |
int col; |
fprintf(hfile, "extern const char %s[];\n", name); |
fprintf(cfile, "const char %s[%d] = {\n", name, size); |
col = 0; |
for (i = 0 ; i < size ; i++) { |
if (i == 0) { |
fputs(" ", cfile); |
} else if ((i & 03) == 0) { |
fputs(",\n ", cfile); |
col = 0; |
} else { |
putc(',', cfile); |
while (++col < 9 * (i & 03)) |
putc(' ', cfile); |
} |
fputs(syntax[i], cfile); |
col += strlen(syntax[i]); |
} |
fputs("\n};\n", cfile); |
} |
/* |
* Output character classification macros (e.g. is_digit). If digits are |
* contiguous, we can test for them quickly. |
*/ |
static char *macro[] = { |
"#define is_digit(c)\t((is_type+SYNBASE)[c] & ISDIGIT)", |
"#define is_alpha(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && isalpha((unsigned char) (c)))", |
"#define is_name(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalpha((unsigned char) (c))))", |
"#define is_in_name(c)\t((c) != UPEOF && ((c) < CTLESC || (c) > CTLENDARI) && ((c) == '_' || isalnum((unsigned char) (c))))", |
"#define is_special(c)\t((is_type+SYNBASE)[c] & (ISSPECL|ISDIGIT))", |
NULL |
}; |
static void |
output_type_macros() |
{ |
char **pp; |
if (digit_contig) |
macro[0] = "#define is_digit(c)\t((unsigned)((c) - '0') <= 9)"; |
for (pp = macro ; *pp ; pp++) |
fprintf(hfile, "%s\n", *pp); |
if (digit_contig) |
fputs("#define digit_val(c)\t((c) - '0')\n", hfile); |
else |
fputs("#define digit_val(c)\t(digit_value[c])\n", hfile); |
} |
/* |
* Output digit conversion table (if digits are not contiguous). |
*/ |
static void |
digit_convert() |
{ |
int maxdigit; |
static char digit[] = "0123456789"; |
char *p; |
int i; |
maxdigit = 0; |
for (p = digit ; *p ; p++) |
if (*p > maxdigit) |
maxdigit = *p; |
fputs("extern const char digit_value[];\n", hfile); |
fputs("\n\nconst char digit_value[] = {\n", cfile); |
for (i = 0 ; i <= maxdigit ; i++) { |
for (p = digit ; *p && *p != i ; p++); |
if (*p == '\0') |
p = digit; |
fprintf(cfile, " %ld,\n", (long)(p - digit)); |
} |
fputs("};\n", cfile); |
} |
/branches/dd/uspace/app/ash/tools/Makefile |
---|
0,0 → 1,56 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
SOURCES = \ |
mkinit.c \ |
mknodes.c \ |
mksyntax.c \ |
mksignames.c |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
OUTPUT := $(addprefix ../,$(basename $(SOURCES))) |
.PHONY: all clean move-output |
all: $(OUTPUT) |
$(OUTPUT): $(OBJECTS) |
$(CC) $< $(LFLAGS) -o $@ |
clean: |
-rm -f $(OUTPUT) $(OBJECTS) |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dd/uspace/app/ash/tools/mksignames.c |
---|
0,0 → 1,400 |
/* signames.c -- Create and write `signames.c', which contains an array of |
signal names. */ |
/* Copyright (C) 1992 Free Software Foundation, Inc. |
This file is part of GNU Bash, the Bourne Again SHell. |
Bash is free software; you can redistribute it and/or modify it under |
the terms of the GNU General Public License as published by the Free |
Software Foundation; either version 2, or (at your option) any later |
version. |
Bash is distributed in the hope that it will be useful, but WITHOUT ANY |
WARRANTY; without even the implied warranty of MERCHANTABILITY or |
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
for more details. |
You should have received a copy of the GNU General Public License along |
with Bash; see the file COPYING. If not, write to the Free Software |
Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ |
#include <stdio.h> |
#include <sys/types.h> |
#include <signal.h> |
#include <stdlib.h> |
#if !defined (NSIG) |
# define NSIG 64 |
#endif |
char *signal_names[2 * NSIG]; |
char *progname; |
#if defined (SIGRTMAX) || defined (SIGRTMIN) |
# define RTLEN 14 |
# define RTLIM 256 |
#endif |
void |
initialize_signames () |
{ |
register int i; |
#if defined (SIGRTMAX) || defined (SIGRTMIN) |
int rtmin, rtmax, rtcnt; |
#endif |
for (i = 1; i < sizeof(signal_names)/sizeof(signal_names[0]); i++) |
signal_names[i] = (char *)NULL; |
/* `signal' 0 is what we do on exit. */ |
signal_names[0] = "EXIT"; |
/* Place signal names which can be aliases for more common signal |
names first. This allows (for example) SIGABRT to overwrite SIGLOST. */ |
/* POSIX 1003.1b-1993 real time signals, but take care of incomplete |
implementations. Acoording to the standard, both, SIGRTMIN and |
SIGRTMAX must be defined, SIGRTMIN must be stricly less than |
SIGRTMAX, and the difference must be at least 7, that is, there |
must be at least eight distinct real time signals. */ |
/* The generated signal names are SIGRTMIN, SIGRTMIN+1, ..., |
SIGRTMIN+x, SIGRTMAX-x, ..., SIGRTMAX-1, SIGRTMAX. If the number |
of RT signals is odd, there is an extra SIGRTMIN+(x+1). |
These names are the ones used by ksh and /usr/xpg4/bin/sh on SunOS5. */ |
#if defined (SIGRTMIN) |
rtmin = SIGRTMIN; |
signal_names[rtmin] = "SIGRTMIN"; |
#endif |
#if defined (SIGRTMAX) |
rtmax = SIGRTMAX; |
signal_names[rtmax] = "SIGRTMAX"; |
#endif |
#if defined (SIGRTMAX) && defined (SIGRTMIN) |
if (rtmax > rtmin) |
{ |
rtcnt = (rtmax - rtmin - 1) / 2; |
/* croak if there are too many RT signals */ |
if (rtcnt >= RTLIM/2) |
{ |
rtcnt = RTLIM/2-1; |
fprintf(stderr, "%s: error: more than %i real time signals, fix `%s'\n", |
progname, RTLIM, progname); |
} |
for (i = 1; i <= rtcnt; i++) |
{ |
signal_names[rtmin+i] = (char *)malloc(RTLEN); |
sprintf (signal_names[rtmin+i], "SIGRTMIN+%d", i); |
signal_names[rtmax-i] = (char *)malloc(RTLEN); |
sprintf (signal_names[rtmax-i], "SIGRTMAX-%d", i); |
} |
if (rtcnt < RTLIM/2-1 && rtcnt != (rtmax-rtmin)/2) |
{ |
/* Need an extra RTMIN signal */ |
signal_names[rtmin+rtcnt+1] = (char *)malloc(RTLEN); |
sprintf (signal_names[rtmin+rtcnt+1], "SIGRTMIN+%d", rtcnt+1); |
} |
} |
#endif /* SIGRTMIN && SIGRTMAX */ |
/* AIX */ |
#if defined (SIGLOST) /* resource lost (eg, record-lock lost) */ |
signal_names[SIGLOST] = "SIGLOST"; |
#endif |
#if defined (SIGMSG) /* HFT input data pending */ |
signal_names[SIGMSG] = "SIGMSG"; |
#endif |
#if defined (SIGDANGER) /* system crash imminent */ |
signal_names[SIGDANGER] = "SIGDANGER"; |
#endif |
#if defined (SIGMIGRATE) /* migrate process to another CPU */ |
signal_names[SIGMIGRATE] = "SIGMIGRATE"; |
#endif |
#if defined (SIGPRE) /* programming error */ |
signal_names[SIGPRE] = "SIGPRE"; |
#endif |
#if defined (SIGVIRT) /* AIX virtual time alarm */ |
signal_names[SIGVIRT] = "SIGVIRT"; |
#endif |
#if defined (SIGALRM1) /* m:n condition variables */ |
signal_names[SIGALRM1] = "SIGALRM1"; |
#endif |
#if defined (SIGWAITING) /* m:n scheduling */ |
signal_names[SIGWAITING] = "SIGWAITING"; |
#endif |
#if defined (SIGGRANT) /* HFT monitor mode granted */ |
signal_names[SIGGRANT] = "SIGGRANT"; |
#endif |
#if defined (SIGKAP) /* keep alive poll from native keyboard */ |
signal_names[SIGKAP] = "SIGKAP"; |
#endif |
#if defined (SIGRETRACT) /* HFT monitor mode retracted */ |
signal_names[SIGRETRACT] = "SIGRETRACT"; |
#endif |
#if defined (SIGSOUND) /* HFT sound sequence has completed */ |
signal_names[SIGSOUND] = "SIGSOUND"; |
#endif |
#if defined (SIGSAK) /* Secure Attention Key */ |
signal_names[SIGSAK] = "SIGSAK"; |
#endif |
/* SunOS5 */ |
#if defined (SIGLWP) /* special signal used by thread library */ |
signal_names[SIGLWP] = "SIGLWP"; |
#endif |
#if defined (SIGFREEZE) /* special signal used by CPR */ |
signal_names[SIGFREEZE] = "SIGFREEZE"; |
#endif |
#if defined (SIGTHAW) /* special signal used by CPR */ |
signal_names[SIGTHAW] = "SIGTHAW"; |
#endif |
#if defined (SIGCANCEL) /* thread cancellation signal used by libthread */ |
signal_names[SIGCANCEL] = "SIGCANCEL"; |
#endif |
/* HP-UX */ |
#if defined (SIGDIL) /* DIL signal (?) */ |
signal_names[SIGDIL] = "SIGDIL"; |
#endif |
/* System V */ |
#if defined (SIGCLD) /* Like SIGCHLD. */ |
signal_names[SIGCLD] = "SIGCLD"; |
#endif |
#if defined (SIGPWR) /* power state indication */ |
signal_names[SIGPWR] = "SIGPWR"; |
#endif |
#if defined (SIGPOLL) /* Pollable event (for streams) */ |
signal_names[SIGPOLL] = "SIGPOLL"; |
#endif |
/* Unknown */ |
#if defined (SIGWINDOW) |
signal_names[SIGWINDOW] = "SIGWINDOW"; |
#endif |
/* Common */ |
#if defined (SIGHUP) /* hangup */ |
signal_names[SIGHUP] = "SIGHUP"; |
#endif |
#if defined (SIGINT) /* interrupt */ |
signal_names[SIGINT] = "SIGINT"; |
#endif |
#if defined (SIGQUIT) /* quit */ |
signal_names[SIGQUIT] = "SIGQUIT"; |
#endif |
#if defined (SIGILL) /* illegal instruction (not reset when caught) */ |
signal_names[SIGILL] = "SIGILL"; |
#endif |
#if defined (SIGTRAP) /* trace trap (not reset when caught) */ |
signal_names[SIGTRAP] = "SIGTRAP"; |
#endif |
#if defined (SIGIOT) /* IOT instruction */ |
signal_names[SIGIOT] = "SIGIOT"; |
#endif |
#if defined (SIGABRT) /* Cause current process to dump core. */ |
signal_names[SIGABRT] = "SIGABRT"; |
#endif |
#if defined (SIGEMT) /* EMT instruction */ |
signal_names[SIGEMT] = "SIGEMT"; |
#endif |
#if defined (SIGFPE) /* floating point exception */ |
signal_names[SIGFPE] = "SIGFPE"; |
#endif |
#if defined (SIGKILL) /* kill (cannot be caught or ignored) */ |
signal_names[SIGKILL] = "SIGKILL"; |
#endif |
#if defined (SIGBUS) /* bus error */ |
signal_names[SIGBUS] = "SIGBUS"; |
#endif |
#if defined (SIGSEGV) /* segmentation violation */ |
signal_names[SIGSEGV] = "SIGSEGV"; |
#endif |
#if defined (SIGSYS) /* bad argument to system call */ |
signal_names[SIGSYS] = "SIGSYS"; |
#endif |
#if defined (SIGPIPE) /* write on a pipe with no one to read it */ |
signal_names[SIGPIPE] = "SIGPIPE"; |
#endif |
#if defined (SIGALRM) /* alarm clock */ |
signal_names[SIGALRM] = "SIGALRM"; |
#endif |
#if defined (SIGTERM) /* software termination signal from kill */ |
signal_names[SIGTERM] = "SIGTERM"; |
#endif |
#if defined (SIGURG) /* urgent condition on IO channel */ |
signal_names[SIGURG] = "SIGURG"; |
#endif |
#if defined (SIGSTOP) /* sendable stop signal not from tty */ |
signal_names[SIGSTOP] = "SIGSTOP"; |
#endif |
#if defined (SIGTSTP) /* stop signal from tty */ |
signal_names[SIGTSTP] = "SIGTSTP"; |
#endif |
#if defined (SIGCONT) /* continue a stopped process */ |
signal_names[SIGCONT] = "SIGCONT"; |
#endif |
#if defined (SIGCHLD) /* to parent on child stop or exit */ |
signal_names[SIGCHLD] = "SIGCHLD"; |
#endif |
#if defined (SIGTTIN) /* to readers pgrp upon background tty read */ |
signal_names[SIGTTIN] = "SIGTTIN"; |
#endif |
#if defined (SIGTTOU) /* like TTIN for output if (tp->t_local<OSTOP) */ |
signal_names[SIGTTOU] = "SIGTTOU"; |
#endif |
#if defined (SIGIO) /* input/output possible signal */ |
signal_names[SIGIO] = "SIGIO"; |
#endif |
#if defined (SIGXCPU) /* exceeded CPU time limit */ |
signal_names[SIGXCPU] = "SIGXCPU"; |
#endif |
#if defined (SIGXFSZ) /* exceeded file size limit */ |
signal_names[SIGXFSZ] = "SIGXFSZ"; |
#endif |
#if defined (SIGVTALRM) /* virtual time alarm */ |
signal_names[SIGVTALRM] = "SIGVTALRM"; |
#endif |
#if defined (SIGPROF) /* profiling time alarm */ |
signal_names[SIGPROF] = "SIGPROF"; |
#endif |
#if defined (SIGWINCH) /* window changed */ |
signal_names[SIGWINCH] = "SIGWINCH"; |
#endif |
/* 4.4 BSD */ |
#if defined (SIGINFO) && !defined (_SEQUENT_) /* information request */ |
signal_names[SIGINFO] = "SIGINFO"; |
#endif |
#if defined (SIGUSR1) /* user defined signal 1 */ |
signal_names[SIGUSR1] = "SIGUSR1"; |
#endif |
#if defined (SIGUSR2) /* user defined signal 2 */ |
signal_names[SIGUSR2] = "SIGUSR2"; |
#endif |
#if defined (SIGKILLTHR) /* BeOS: Kill Thread */ |
signal_names[SIGKILLTHR] = "SIGKILLTHR"; |
#endif |
for (i = 0; i < NSIG; i++) |
if (signal_names[i] == (char *)NULL) |
{ |
signal_names[i] = (char *)malloc (18); |
sprintf (signal_names[i], "SIGJUNK(%d)", i); |
} |
signal_names[NSIG] = "DEBUG"; |
} |
void |
write_signames (stream) |
FILE *stream; |
{ |
register int i; |
fprintf (stream, "/* This file was automatically created by %s.\n", |
progname); |
fprintf (stream, " Do not edit. Edit support/mksignames.c instead. */\n\n"); |
fprintf (stream, "#include <signal.h>\n\n"); |
fprintf (stream, |
"/* A translation list so we can be polite to our users. */\n"); |
fprintf (stream, "char *signal_names[NSIG + 2] = {\n"); |
for (i = 0; i <= NSIG; i++) |
fprintf (stream, " \"%s\",\n", signal_names[i]); |
fprintf (stream, " (char *)0x0,\n"); |
fprintf (stream, "};\n"); |
} |
int |
main (argc, argv) |
int argc; |
char **argv; |
{ |
char *stream_name; |
FILE *stream; |
progname = argv[0]; |
if (argc == 1) |
{ |
stream_name = "signames.c"; |
} |
else if (argc == 2) |
{ |
stream_name = argv[1]; |
} |
else |
{ |
fprintf (stderr, "Usage: %s [output-file]\n", progname); |
exit (1); |
} |
stream = fopen (stream_name, "w"); |
if (!stream) |
{ |
fprintf (stderr, "%s: %s: cannot open for writing\n", |
progname, stream_name); |
exit (2); |
} |
initialize_signames (); |
write_signames (stream); |
exit (0); |
} |
/branches/dd/uspace/app/ash/tools/mknodes.c |
---|
0,0 → 1,492 |
/* $NetBSD: mknodes.c,v 1.18 2000/07/27 04:06:49 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#ifndef lint |
static const char copyright[] = |
"@(#) Copyright (c) 1991, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"; |
#endif /* not lint */ |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)mknodes.c 8.2 (Berkeley) 5/4/95"; |
#else |
static const char rcsid[] = |
"$NetBSD: mknodes.c,v 1.18 2000/07/27 04:06:49 cgd Exp $"; |
#endif |
#endif /* not lint */ |
/* |
* This program reads the nodetypes file and nodes.c.pat file. It generates |
* the files nodes.h and nodes.c. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#ifdef __STDC__ |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#define MAXTYPES 50 /* max number of node types */ |
#define MAXFIELDS 20 /* max fields in a structure */ |
#define BUFLEN 100 /* size of character buffers */ |
/* field types */ |
#define T_NODE 1 /* union node *field */ |
#define T_NODELIST 2 /* struct nodelist *field */ |
#define T_STRING 3 |
#define T_INT 4 /* int field */ |
#define T_OTHER 5 /* other */ |
#define T_TEMP 6 /* don't copy this field */ |
struct field { /* a structure field */ |
char *name; /* name of field */ |
int type; /* type of field */ |
char *decl; /* declaration of field */ |
}; |
struct str { /* struct representing a node structure */ |
char *tag; /* structure tag */ |
int nfields; /* number of fields in the structure */ |
struct field field[MAXFIELDS]; /* the fields of the structure */ |
int done; /* set if fully parsed */ |
}; |
static int ntypes; /* number of node types */ |
static char *nodename[MAXTYPES]; /* names of the nodes */ |
static struct str *nodestr[MAXTYPES]; /* type of structure used by the node */ |
static int nstr; /* number of structures */ |
static struct str str[MAXTYPES]; /* the structures */ |
static struct str *curstr; /* current structure */ |
static FILE *infp; |
static char line[1024]; |
static int linno; |
static char *linep; |
static void parsenode(void); |
static void parsefield(void); |
static void output(char *); |
static void outsizes(FILE *); |
static void outfunc(FILE *, int); |
static void indent(int, FILE *); |
static int nextfield(char *); |
static void skipbl(void); |
static int readline(void); |
static void error(const char *, ...); |
static char *savestr(const char *); |
int main(int, char **); |
int |
main(argc, argv) |
int argc; |
char **argv; |
{ |
/* |
* some versions of linux complain: initializer element is not |
* constant if this is done at compile time. |
*/ |
infp = stdin; |
if (argc != 3) |
error("usage: mknodes file"); |
if ((infp = fopen(argv[1], "r")) == NULL) |
error("Can't open %s", argv[1]); |
while (readline()) { |
if (line[0] == ' ' || line[0] == '\t') |
parsefield(); |
else if (line[0] != '\0') |
parsenode(); |
} |
output(argv[2]); |
exit(0); |
/* NOTREACHED */ |
} |
static void |
parsenode() |
{ |
char name[BUFLEN]; |
char tag[BUFLEN]; |
struct str *sp; |
if (curstr && curstr->nfields > 0) |
curstr->done = 1; |
nextfield(name); |
if (! nextfield(tag)) |
error("Tag expected"); |
if (*linep != '\0') |
error("Garbage at end of line"); |
nodename[ntypes] = savestr(name); |
for (sp = str ; sp < str + nstr ; sp++) { |
if (strcmp(sp->tag, tag) == 0) |
break; |
} |
if (sp >= str + nstr) { |
sp->tag = savestr(tag); |
sp->nfields = 0; |
curstr = sp; |
nstr++; |
} |
nodestr[ntypes] = sp; |
ntypes++; |
} |
static void |
parsefield() |
{ |
char name[BUFLEN]; |
char type[BUFLEN]; |
char decl[2 * BUFLEN]; |
struct field *fp; |
if (curstr == NULL || curstr->done) |
error("No current structure to add field to"); |
if (! nextfield(name)) |
error("No field name"); |
if (! nextfield(type)) |
error("No field type"); |
fp = &curstr->field[curstr->nfields]; |
fp->name = savestr(name); |
if (strcmp(type, "nodeptr") == 0) { |
fp->type = T_NODE; |
sprintf(decl, "union node *%s", name); |
} else if (strcmp(type, "nodelist") == 0) { |
fp->type = T_NODELIST; |
sprintf(decl, "struct nodelist *%s", name); |
} else if (strcmp(type, "string") == 0) { |
fp->type = T_STRING; |
sprintf(decl, "char *%s", name); |
} else if (strcmp(type, "int") == 0) { |
fp->type = T_INT; |
sprintf(decl, "int %s", name); |
} else if (strcmp(type, "other") == 0) { |
fp->type = T_OTHER; |
} else if (strcmp(type, "temp") == 0) { |
fp->type = T_TEMP; |
} else { |
error("Unknown type %s", type); |
} |
if (fp->type == T_OTHER || fp->type == T_TEMP) { |
skipbl(); |
fp->decl = savestr(linep); |
} else { |
if (*linep) |
error("Garbage at end of line"); |
fp->decl = savestr(decl); |
} |
curstr->nfields++; |
} |
char writer[] = "\ |
/*\n\ |
* This file was generated by the mknodes program.\n\ |
*/\n\ |
\n"; |
static void |
output(file) |
char *file; |
{ |
FILE *hfile; |
FILE *cfile; |
FILE *patfile; |
int i; |
struct str *sp; |
struct field *fp; |
char *p; |
if ((patfile = fopen(file, "r")) == NULL) |
error("Can't open %s", file); |
if ((hfile = fopen("nodes.h", "w")) == NULL) |
error("Can't create nodes.h"); |
if ((cfile = fopen("nodes.c", "w")) == NULL) |
error("Can't create nodes.c"); |
fputs(writer, hfile); |
for (i = 0 ; i < ntypes ; i++) |
fprintf(hfile, "#define %s %d\n", nodename[i], i); |
fputs("\n\n\n", hfile); |
for (sp = str ; sp < &str[nstr] ; sp++) { |
fprintf(hfile, "struct %s {\n", sp->tag); |
for (i = sp->nfields, fp = sp->field ; --i >= 0 ; fp++) { |
fprintf(hfile, " %s;\n", fp->decl); |
} |
fputs("};\n\n\n", hfile); |
} |
fputs("union node {\n", hfile); |
fprintf(hfile, " int type;\n"); |
for (sp = str ; sp < &str[nstr] ; sp++) { |
fprintf(hfile, " struct %s %s;\n", sp->tag, sp->tag); |
} |
fputs("};\n\n\n", hfile); |
fputs("struct nodelist {\n", hfile); |
fputs("\tstruct nodelist *next;\n", hfile); |
fputs("\tunion node *n;\n", hfile); |
fputs("};\n\n\n", hfile); |
fputs("#ifdef __STDC__\n", hfile); |
fputs("union node *copyfunc(union node *);\n", hfile); |
fputs("void freefunc(union node *);\n", hfile); |
fputs("#else\n", hfile); |
fputs("union node *copyfunc();\n", hfile); |
fputs("void freefunc();\n", hfile); |
fputs("#endif\n", hfile); |
fputs(writer, cfile); |
while (fgets(line, sizeof line, patfile) != NULL) { |
for (p = line ; *p == ' ' || *p == '\t' ; p++); |
if (strcmp(p, "%SIZES\n") == 0) |
outsizes(cfile); |
else if (strcmp(p, "%CALCSIZE\n") == 0) |
outfunc(cfile, 1); |
else if (strcmp(p, "%COPY\n") == 0) |
outfunc(cfile, 0); |
else |
fputs(line, cfile); |
} |
} |
static void |
outsizes(cfile) |
FILE *cfile; |
{ |
int i; |
fprintf(cfile, "static const short nodesize[%d] = {\n", ntypes); |
for (i = 0 ; i < ntypes ; i++) { |
fprintf(cfile, " ALIGN(sizeof (struct %s)),\n", nodestr[i]->tag); |
} |
fprintf(cfile, "};\n"); |
} |
static void |
outfunc(cfile, calcsize) |
FILE *cfile; |
int calcsize; |
{ |
struct str *sp; |
struct field *fp; |
int i; |
fputs(" if (n == NULL)\n", cfile); |
if (calcsize) |
fputs(" return;\n", cfile); |
else |
fputs(" return NULL;\n", cfile); |
if (calcsize) |
fputs(" funcblocksize += nodesize[n->type];\n", cfile); |
else { |
fputs(" new = funcblock;\n", cfile); |
fputs(" funcblock = (char *) funcblock + nodesize[n->type];\n", cfile); |
} |
fputs(" switch (n->type) {\n", cfile); |
for (sp = str ; sp < &str[nstr] ; sp++) { |
for (i = 0 ; i < ntypes ; i++) { |
if (nodestr[i] == sp) |
fprintf(cfile, " case %s:\n", nodename[i]); |
} |
for (i = sp->nfields ; --i >= 1 ; ) { |
fp = &sp->field[i]; |
switch (fp->type) { |
case T_NODE: |
if (calcsize) { |
indent(12, cfile); |
fprintf(cfile, "calcsize(n->%s.%s);\n", |
sp->tag, fp->name); |
} else { |
indent(12, cfile); |
fprintf(cfile, "new->%s.%s = copynode(n->%s.%s);\n", |
sp->tag, fp->name, sp->tag, fp->name); |
} |
break; |
case T_NODELIST: |
if (calcsize) { |
indent(12, cfile); |
fprintf(cfile, "sizenodelist(n->%s.%s);\n", |
sp->tag, fp->name); |
} else { |
indent(12, cfile); |
fprintf(cfile, "new->%s.%s = copynodelist(n->%s.%s);\n", |
sp->tag, fp->name, sp->tag, fp->name); |
} |
break; |
case T_STRING: |
if (calcsize) { |
indent(12, cfile); |
fprintf(cfile, "funcstringsize += strlen(n->%s.%s) + 1;\n", |
sp->tag, fp->name); |
} else { |
indent(12, cfile); |
fprintf(cfile, "new->%s.%s = nodesavestr(n->%s.%s);\n", |
sp->tag, fp->name, sp->tag, fp->name); |
} |
break; |
case T_INT: |
case T_OTHER: |
if (! calcsize) { |
indent(12, cfile); |
fprintf(cfile, "new->%s.%s = n->%s.%s;\n", |
sp->tag, fp->name, sp->tag, fp->name); |
} |
break; |
} |
} |
indent(12, cfile); |
fputs("break;\n", cfile); |
} |
fputs(" };\n", cfile); |
if (! calcsize) |
fputs(" new->type = n->type;\n", cfile); |
} |
static void |
indent(amount, fp) |
int amount; |
FILE *fp; |
{ |
while (amount >= 8) { |
putc('\t', fp); |
amount -= 8; |
} |
while (--amount >= 0) { |
putc(' ', fp); |
} |
} |
static int |
nextfield(buf) |
char *buf; |
{ |
char *p, *q; |
p = linep; |
while (*p == ' ' || *p == '\t') |
p++; |
q = buf; |
while (*p != ' ' && *p != '\t' && *p != '\0') |
*q++ = *p++; |
*q = '\0'; |
linep = p; |
return (q > buf); |
} |
static void |
skipbl() |
{ |
while (*linep == ' ' || *linep == '\t') |
linep++; |
} |
static int |
readline() |
{ |
char *p; |
if (fgets(line, 1024, infp) == NULL) |
return 0; |
for (p = line ; *p != '#' && *p != '\n' && *p != '\0' ; p++); |
while (p > line && (p[-1] == ' ' || p[-1] == '\t')) |
p--; |
*p = '\0'; |
linep = line; |
linno++; |
if (p - line > BUFLEN) |
error("Line too long"); |
return 1; |
} |
static void |
#ifdef __STDC__ |
error(const char *msg, ...) |
#else |
error(va_alist) |
va_dcl |
#endif |
{ |
va_list va; |
#ifdef __STDC__ |
va_start(va, msg); |
#else |
char *msg; |
va_start(va); |
msg = va_arg(va, char *); |
#endif |
(void) fprintf(stderr, "line %d: ", linno); |
(void) vfprintf(stderr, msg, va); |
(void) fputc('\n', stderr); |
va_end(va); |
exit(2); |
/* NOTREACHED */ |
} |
static char * |
savestr(s) |
const char *s; |
{ |
char *p; |
if ((p = malloc(strlen(s) + 1)) == NULL) |
error("Out of space"); |
(void) strcpy(p, s); |
return p; |
} |
/branches/dd/uspace/app/ash/tools/mkinit.c |
---|
0,0 → 1,525 |
/* $NetBSD: mkinit.c,v 1.20 2000/07/18 19:13:20 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#ifndef lint |
static const char copyright[] = |
"@(#) Copyright (c) 1991, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"; |
#endif /* not lint */ |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)mkinit.c 8.2 (Berkeley) 5/4/95"; |
#else |
static const char rcsid[] = |
"$NetBSD: mkinit.c,v 1.20 2000/07/18 19:13:20 cgd Exp $"; |
#endif |
#endif /* not lint */ |
/* |
* This program scans all the source files for code to handle various |
* special events and combines this code into one file. This (allegedly) |
* improves the structure of the program since there is no need for |
* anyone outside of a module to know that that module performs special |
* operations on particular events. |
* |
* Usage: mkinit sourcefile... |
*/ |
#include <sys/types.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <fcntl.h> |
#include <unistd.h> |
/* |
* OUTFILE is the name of the output file. Output is initially written |
* to the file OUTTEMP, which is then moved to OUTFILE. |
*/ |
#define OUTFILE "init.c" |
#define OUTTEMP "init.c.new" |
/* |
* A text structure is basicly just a string that grows as more characters |
* are added onto the end of it. It is implemented as a linked list of |
* blocks of characters. The routines addstr and addchar append a string |
* or a single character, respectively, to a text structure. Writetext |
* writes the contents of a text structure to a file. |
*/ |
#define BLOCKSIZE 512 |
struct text { |
char *nextc; |
int nleft; |
struct block *start; |
struct block *last; |
}; |
struct block { |
struct block *next; |
char text[BLOCKSIZE]; |
}; |
/* |
* There is one event structure for each event that mkinit handles. |
*/ |
struct event { |
char *name; /* name of event (e.g. INIT) */ |
char *routine; /* name of routine called on event */ |
char *comment; /* comment describing routine */ |
struct text code; /* code for handling event */ |
}; |
char writer[] = "\ |
/*\n\ |
* This file was generated by the mkinit program.\n\ |
*/\n\ |
\n"; |
char init[] = "\ |
/*\n\ |
* Initialization code.\n\ |
*/\n"; |
char reset[] = "\ |
/*\n\ |
* This routine is called when an error or an interrupt occurs in an\n\ |
* interactive shell and control is returned to the main command loop.\n\ |
*/\n"; |
char shellproc[] = "\ |
/*\n\ |
* This routine is called to initialize the shell to run a shell procedure.\n\ |
*/\n"; |
struct event event[] = { |
{"INIT", "init", init}, |
{"RESET", "reset", reset}, |
{"SHELLPROC", "initshellproc", shellproc}, |
{NULL, NULL} |
}; |
char *curfile; /* current file */ |
int linno; /* current line */ |
char *header_files[200]; /* list of header files */ |
struct text defines; /* #define statements */ |
struct text decls; /* declarations */ |
int amiddecls; /* for formatting */ |
void readfile(char *); |
int match(char *, char *); |
int gooddefine(char *); |
void doevent(struct event *, FILE *, char *); |
void doinclude(char *); |
void dodecl(char *, FILE *); |
void output(void); |
void addstr(char *, struct text *); |
void addchar(int, struct text *); |
void writetext(struct text *, FILE *); |
FILE *ckfopen(char *, char *); |
void *ckmalloc(int); |
char *savestr(char *); |
void error(char *); |
int main(int, char **); |
#define equal(s1, s2) (strcmp(s1, s2) == 0) |
int |
main(argc, argv) |
int argc; |
char **argv; |
{ |
char **ap; |
header_files[0] = "\"shell.h\""; |
header_files[1] = "\"mystring.h\""; |
header_files[2] = "\"init.h\""; |
for (ap = argv + 1 ; *ap ; ap++) |
readfile(*ap); |
output(); |
rename(OUTTEMP, OUTFILE); |
exit(0); |
/* NOTREACHED */ |
} |
/* |
* Parse an input file. |
*/ |
void |
readfile(fname) |
char *fname; |
{ |
FILE *fp; |
char line[1024]; |
struct event *ep; |
fp = ckfopen(fname, "r"); |
curfile = fname; |
linno = 0; |
amiddecls = 0; |
while (fgets(line, sizeof line, fp) != NULL) { |
linno++; |
for (ep = event ; ep->name ; ep++) { |
if (line[0] == ep->name[0] && match(ep->name, line)) { |
doevent(ep, fp, fname); |
break; |
} |
} |
if (line[0] == 'I' && match("INCLUDE", line)) |
doinclude(line); |
if (line[0] == 'M' && match("MKINIT", line)) |
dodecl(line, fp); |
if (line[0] == '#' && gooddefine(line)) |
addstr(line, &defines); |
if (line[0] == '#' && gooddefine(line)) { |
char *cp; |
char line2[1024]; |
static const char undef[] = "#undef "; |
strcpy(line2, line); |
memcpy(line2, undef, sizeof(undef) - 1); |
cp = line2 + sizeof(undef) - 1; |
while(*cp && (*cp == ' ' || *cp == '\t')) |
cp++; |
while(*cp && *cp != ' ' && *cp != '\t' && *cp != '\n') |
cp++; |
*cp++ = '\n'; *cp = '\0'; |
addstr(line2, &defines); |
addstr(line, &defines); |
} |
} |
fclose(fp); |
} |
int |
match(name, line) |
char *name; |
char *line; |
{ |
char *p, *q; |
p = name, q = line; |
while (*p) { |
if (*p++ != *q++) |
return 0; |
} |
if (*q != '{' && *q != ' ' && *q != '\t' && *q != '\n') |
return 0; |
return 1; |
} |
int |
gooddefine(line) |
char *line; |
{ |
char *p; |
if (! match("#define", line)) |
return 0; /* not a define */ |
p = line + 7; |
while (*p == ' ' || *p == '\t') |
p++; |
while (*p != ' ' && *p != '\t') { |
if (*p == '(') |
return 0; /* macro definition */ |
p++; |
} |
while (*p != '\n' && *p != '\0') |
p++; |
if (p[-1] == '\\') |
return 0; /* multi-line definition */ |
return 1; |
} |
void |
doevent(ep, fp, fname) |
struct event *ep; |
FILE *fp; |
char *fname; |
{ |
char line[1024]; |
int indent; |
char *p; |
sprintf(line, "\n /* from %s: */\n", fname); |
addstr(line, &ep->code); |
addstr(" {\n", &ep->code); |
for (;;) { |
linno++; |
if (fgets(line, sizeof line, fp) == NULL) |
error("Unexpected EOF"); |
if (equal(line, "}\n")) |
break; |
indent = 6; |
for (p = line ; *p == '\t' ; p++) |
indent += 8; |
for ( ; *p == ' ' ; p++) |
indent++; |
if (*p == '\n' || *p == '#') |
indent = 0; |
while (indent >= 8) { |
addchar('\t', &ep->code); |
indent -= 8; |
} |
while (indent > 0) { |
addchar(' ', &ep->code); |
indent--; |
} |
addstr(p, &ep->code); |
} |
addstr(" }\n", &ep->code); |
} |
void |
doinclude(line) |
char *line; |
{ |
char *p; |
char *name; |
char **pp; |
for (p = line ; *p != '"' && *p != '<' && *p != '\0' ; p++); |
if (*p == '\0') |
error("Expecting '\"' or '<'"); |
name = p; |
while (*p != ' ' && *p != '\t' && *p != '\n') |
p++; |
if (p[-1] != '"' && p[-1] != '>') |
error("Missing terminator"); |
*p = '\0'; |
/* name now contains the name of the include file */ |
for (pp = header_files ; *pp && ! equal(*pp, name) ; pp++); |
if (*pp == NULL) |
*pp = savestr(name); |
} |
void |
dodecl(line1, fp) |
char *line1; |
FILE *fp; |
{ |
char line[1024]; |
char *p, *q; |
if (strcmp(line1, "MKINIT\n") == 0) { /* start of struct/union decl */ |
addchar('\n', &decls); |
do { |
linno++; |
if (fgets(line, sizeof line, fp) == NULL) |
error("Unterminated structure declaration"); |
addstr(line, &decls); |
} while (line[0] != '}'); |
amiddecls = 0; |
} else { |
if (! amiddecls) |
addchar('\n', &decls); |
q = NULL; |
for (p = line1 + 6 ; *p && strchr("=/\n", *p) == NULL; p++) |
continue; |
if (*p == '=') { /* eliminate initialization */ |
for (q = p ; *q && *q != ';' ; q++); |
if (*q == '\0') |
q = NULL; |
else { |
while (p[-1] == ' ') |
p--; |
*p = '\0'; |
} |
} |
addstr("extern", &decls); |
addstr(line1 + 6, &decls); |
if (q != NULL) |
addstr(q, &decls); |
amiddecls = 1; |
} |
} |
/* |
* Write the output to the file OUTTEMP. |
*/ |
void |
output() { |
FILE *fp; |
char **pp; |
struct event *ep; |
fp = ckfopen(OUTTEMP, "w"); |
fputs(writer, fp); |
for (pp = header_files ; *pp ; pp++) |
fprintf(fp, "#include %s\n", *pp); |
fputs("\n\n\n", fp); |
writetext(&defines, fp); |
fputs("\n\n", fp); |
writetext(&decls, fp); |
for (ep = event ; ep->name ; ep++) { |
fputs("\n\n\n", fp); |
fputs(ep->comment, fp); |
fprintf(fp, "\nvoid\n%s() {\n", ep->routine); |
writetext(&ep->code, fp); |
fprintf(fp, "}\n"); |
} |
fclose(fp); |
} |
/* |
* A text structure is simply a block of text that is kept in memory. |
* Addstr appends a string to the text struct, and addchar appends a single |
* character. |
*/ |
void |
addstr(s, text) |
char *s; |
struct text *text; |
{ |
while (*s) { |
if (--text->nleft < 0) |
addchar(*s++, text); |
else |
*text->nextc++ = *s++; |
} |
} |
void |
addchar(c, text) |
int c; |
struct text *text; |
{ |
struct block *bp; |
if (--text->nleft < 0) { |
bp = ckmalloc(sizeof *bp); |
if (text->start == NULL) |
text->start = bp; |
else |
text->last->next = bp; |
text->last = bp; |
text->nextc = bp->text; |
text->nleft = BLOCKSIZE - 1; |
} |
*text->nextc++ = c; |
} |
/* |
* Write the contents of a text structure to a file. |
*/ |
void |
writetext(text, fp) |
struct text *text; |
FILE *fp; |
{ |
struct block *bp; |
if (text->start != NULL) { |
for (bp = text->start ; bp != text->last ; bp = bp->next) |
fwrite(bp->text, sizeof (char), BLOCKSIZE, fp); |
fwrite(bp->text, sizeof (char), BLOCKSIZE - text->nleft, fp); |
} |
} |
FILE * |
ckfopen(file, mode) |
char *file; |
char *mode; |
{ |
FILE *fp; |
if ((fp = fopen(file, mode)) == NULL) { |
fprintf(stderr, "Can't open %s\n", file); |
exit(2); |
} |
return fp; |
} |
void * |
ckmalloc(nbytes) |
int nbytes; |
{ |
char *p; |
if ((p = malloc(nbytes)) == NULL) |
error("Out of space"); |
return p; |
} |
char * |
savestr(s) |
char *s; |
{ |
char *p; |
p = ckmalloc(strlen(s) + 1); |
strcpy(p, s); |
return p; |
} |
void |
error(msg) |
char *msg; |
{ |
if (curfile != NULL) |
fprintf(stderr, "%s:%d: ", curfile, linno); |
fprintf(stderr, "%s\n", msg); |
exit(2); |
/* NOTREACHED */ |
} |
/branches/dd/uspace/app/ash/Makefile |
---|
0,0 → 1,180 |
# |
# Copyright (c) 2005 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
include ../../../version |
include ../../Makefile.config |
## Setup toolchain |
# |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += \ |
-DSHELL \ |
-I. \ |
-DNO_HISTORY \ |
-DBSD=1 \ |
-DSMALL \ |
-D_GNU_SOURCE \ |
-DGLOB_BROKEN \ |
-D__COPYRIGHT\(x\)= \ |
-D__RCSID\(x\)= |
# -D_DIAGASSERT\(x\)= \ |
# -DHETIO |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
DEFS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
## Sources |
# |
OUTPUT = sh |
SHSRCS = \ |
fake.c \ |
alias.c \ |
cd.c \ |
bltin/echo.c \ |
error.c \ |
eval.c \ |
exec.c \ |
expand.c \ |
hetio.c \ |
histedit.c \ |
input.c \ |
jobs.c \ |
mail.c \ |
main.c \ |
memalloc.c \ |
miscbltin.c \ |
mystring.c \ |
options.c \ |
output.c \ |
parser.c \ |
redir.c \ |
show.c \ |
setmode.c \ |
bltin/test.c \ |
bltin/times.c \ |
trap.c \ |
var.c |
GENSRCS = \ |
builtins.c \ |
init.c \ |
nodes.c \ |
syntax.c \ |
signames.c |
# lex.yy.c \ |
# arith.c \ |
# arith.h \ |
GENHEADERS = \ |
token.h \ |
nodes.h \ |
syntax.h \ |
builtins.h |
SOURCES = ${SHSRCS} ${GENSRCS} |
SUBDIRS = tools |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
.PHONY: all clean depend disasm all-subdirs |
all: all-subdirs $(OUTPUT) disasm |
all-subdirs: |
for i in $(SUBDIRS); do \ |
echo "make all in $$i..."; \ |
make -C $$i all; \ |
done |
-include Makefile.depend |
.ORDER: builtins.c builtins.h |
builtins.c builtins.h: mkbuiltins builtins.def |
sh mkbuiltins shell.h builtins.def `pwd` |
INIT_DEPS = alias.c eval.c exec.c input.c jobs.c options.c parser.c \ |
redir.c trap.c var.c output.c |
init.c: mkinit $(INIT_DEPS) |
./mkinit $(INIT_DEPS) |
signames.c: mksignames |
./mksignames |
nodes.c nodes.h: mknodes nodetypes nodes.c.pat |
./mknodes ./nodetypes ./nodes.c.pat |
syntax.c syntax.h: mksyntax |
./mksyntax |
#arith.c arith.h: arith.y |
# yacc -d arith.y |
# mv y.tab.h arith.h |
# mv y.tab.c arith.c |
token.h: mktokens |
sh ./mktokens |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
-rm -f $(GENSRCS) $(GENHEADERS) $(OBJECTS) |
for i in $(SUBDIRS); do \ |
echo "make clean in $$i..."; \ |
make -C $$i clean; \ |
done |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) $(GENHEADERS) > Makefile.depend |
$(OUTPUT): $(GENSRCS) $(GENHEADERS) $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.s |
$(AS) $(AFLAGS) $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dd/uspace/app/ash/setmode.c |
---|
0,0 → 1,486 |
/* $NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $ */ |
/* |
* Copyright (c) 1989, 1993, 1994 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Dave Borman at Cray Research, Inc. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#if defined(LIBC_SCCS) && !defined(lint) |
#if 0 |
static char sccsid[] = "@(#)setmode.c 8.2 (Berkeley) 3/25/94"; |
#else |
__RCSID("$NetBSD: setmode.c,v 1.28 2000/01/25 15:43:43 enami Exp $"); |
#endif |
#endif /* LIBC_SCCS and not lint */ |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <assert.h> |
#include <ctype.h> |
#include <errno.h> |
#include <signal.h> |
#include <stdlib.h> |
#include <unistd.h> |
#ifdef SETMODE_DEBUG |
#include <stdio.h> |
#endif |
#ifdef __weak_alias |
__weak_alias(getmode,_getmode) |
__weak_alias(setmode,_setmode) |
#endif |
#ifdef __GLIBC__ |
#define S_ISTXT __S_ISVTX |
#endif |
#define SET_LEN 6 /* initial # of bitcmd struct to malloc */ |
#define SET_LEN_INCR 4 /* # of bitcmd structs to add as needed */ |
typedef struct bitcmd { |
char cmd; |
char cmd2; |
mode_t bits; |
} BITCMD; |
#define CMD2_CLR 0x01 |
#define CMD2_SET 0x02 |
#define CMD2_GBITS 0x04 |
#define CMD2_OBITS 0x08 |
#define CMD2_UBITS 0x10 |
static BITCMD *addcmd (BITCMD *, int, int, int, u_int); |
static void compress_mode (BITCMD *); |
#ifdef SETMODE_DEBUG |
static void dumpmode (BITCMD *); |
#endif |
/* |
* Given the old mode and an array of bitcmd structures, apply the operations |
* described in the bitcmd structures to the old mode, and return the new mode. |
* Note that there is no '=' command; a strict assignment is just a '-' (clear |
* bits) followed by a '+' (set bits). |
*/ |
mode_t |
getmode(bbox, omode) |
const void *bbox; |
mode_t omode; |
{ |
const BITCMD *set; |
mode_t clrval, newmode, value; |
_DIAGASSERT(bbox != NULL); |
set = (const BITCMD *)bbox; |
newmode = omode; |
for (value = 0;; set++) |
switch(set->cmd) { |
/* |
* When copying the user, group or other bits around, we "know" |
* where the bits are in the mode so that we can do shifts to |
* copy them around. If we don't use shifts, it gets real |
* grundgy with lots of single bit checks and bit sets. |
*/ |
case 'u': |
value = (newmode & S_IRWXU) >> 6; |
goto common; |
case 'g': |
value = (newmode & S_IRWXG) >> 3; |
goto common; |
case 'o': |
value = newmode & S_IRWXO; |
common: if (set->cmd2 & CMD2_CLR) { |
clrval = |
(set->cmd2 & CMD2_SET) ? S_IRWXO : value; |
if (set->cmd2 & CMD2_UBITS) |
newmode &= ~((clrval<<6) & set->bits); |
if (set->cmd2 & CMD2_GBITS) |
newmode &= ~((clrval<<3) & set->bits); |
if (set->cmd2 & CMD2_OBITS) |
newmode &= ~(clrval & set->bits); |
} |
if (set->cmd2 & CMD2_SET) { |
if (set->cmd2 & CMD2_UBITS) |
newmode |= (value<<6) & set->bits; |
if (set->cmd2 & CMD2_GBITS) |
newmode |= (value<<3) & set->bits; |
if (set->cmd2 & CMD2_OBITS) |
newmode |= value & set->bits; |
} |
break; |
case '+': |
newmode |= set->bits; |
break; |
case '-': |
newmode &= ~set->bits; |
break; |
case 'X': |
if (omode & (S_IFDIR|S_IXUSR|S_IXGRP|S_IXOTH)) |
newmode |= set->bits; |
break; |
case '\0': |
default: |
#ifdef SETMODE_DEBUG |
(void)printf("getmode:%04o -> %04o\n", omode, newmode); |
#endif |
return (newmode); |
} |
} |
#define ADDCMD(a, b, c, d) do { \ |
if (set >= endset) { \ |
BITCMD *newset; \ |
setlen += SET_LEN_INCR; \ |
newset = realloc(saveset, sizeof(BITCMD) * setlen); \ |
if (newset == NULL) { \ |
free(saveset); \ |
return (NULL); \ |
} \ |
set = newset + (set - saveset); \ |
saveset = newset; \ |
endset = newset + (setlen - 2); \ |
} \ |
set = addcmd(set, (a), (b), (c), (d)); \ |
} while (/*CONSTCOND*/0) |
#define STANDARD_BITS (S_ISUID|S_ISGID|S_IRWXU|S_IRWXG|S_IRWXO) |
void * |
setmode(p) |
const char *p; |
{ |
int perm, who; |
char op, *ep; |
BITCMD *set, *saveset, *endset; |
sigset_t sigset, sigoset; |
mode_t mask; |
int equalopdone = 0; /* pacify gcc */ |
int permXbits, setlen; |
if (!*p) |
return (NULL); |
/* |
* Get a copy of the mask for the permissions that are mask relative. |
* Flip the bits, we want what's not set. Since it's possible that |
* the caller is opening files inside a signal handler, protect them |
* as best we can. |
*/ |
sigfillset(&sigset); |
(void)sigprocmask(SIG_BLOCK, &sigset, &sigoset); |
(void)umask(mask = umask(0)); |
mask = ~mask; |
(void)sigprocmask(SIG_SETMASK, &sigoset, NULL); |
setlen = SET_LEN + 2; |
if ((set = malloc((u_int)(sizeof(BITCMD) * setlen))) == NULL) |
return (NULL); |
saveset = set; |
endset = set + (setlen - 2); |
/* |
* If an absolute number, get it and return; disallow non-octal digits |
* or illegal bits. |
*/ |
if (isdigit((unsigned char)*p)) { |
perm = (mode_t)strtol(p, &ep, 8); |
if (*ep || perm & ~(STANDARD_BITS|S_ISTXT)) { |
free(saveset); |
return (NULL); |
} |
ADDCMD('=', (STANDARD_BITS|S_ISTXT), perm, mask); |
set->cmd = 0; |
return (saveset); |
} |
/* |
* Build list of structures to set/clear/copy bits as described by |
* each clause of the symbolic mode. |
*/ |
for (;;) { |
/* First, find out which bits might be modified. */ |
for (who = 0;; ++p) { |
switch (*p) { |
case 'a': |
who |= STANDARD_BITS; |
break; |
case 'u': |
who |= S_ISUID|S_IRWXU; |
break; |
case 'g': |
who |= S_ISGID|S_IRWXG; |
break; |
case 'o': |
who |= S_IRWXO; |
break; |
default: |
goto getop; |
} |
} |
getop: if ((op = *p++) != '+' && op != '-' && op != '=') { |
free(saveset); |
return (NULL); |
} |
if (op == '=') |
equalopdone = 0; |
who &= ~S_ISTXT; |
for (perm = 0, permXbits = 0;; ++p) { |
switch (*p) { |
case 'r': |
perm |= S_IRUSR|S_IRGRP|S_IROTH; |
break; |
case 's': |
/* |
* If specific bits where requested and |
* only "other" bits ignore set-id. |
*/ |
if (who == 0 || (who & ~S_IRWXO)) |
perm |= S_ISUID|S_ISGID; |
break; |
case 't': |
/* |
* If specific bits where requested and |
* only "other" bits ignore set-id. |
*/ |
if (who == 0 || (who & ~S_IRWXO)) { |
who |= S_ISTXT; |
perm |= S_ISTXT; |
} |
break; |
case 'w': |
perm |= S_IWUSR|S_IWGRP|S_IWOTH; |
break; |
case 'X': |
permXbits = S_IXUSR|S_IXGRP|S_IXOTH; |
break; |
case 'x': |
perm |= S_IXUSR|S_IXGRP|S_IXOTH; |
break; |
case 'u': |
case 'g': |
case 'o': |
/* |
* When ever we hit 'u', 'g', or 'o', we have |
* to flush out any partial mode that we have, |
* and then do the copying of the mode bits. |
*/ |
if (perm) { |
ADDCMD(op, who, perm, mask); |
perm = 0; |
} |
if (op == '=') |
equalopdone = 1; |
if (op == '+' && permXbits) { |
ADDCMD('X', who, permXbits, mask); |
permXbits = 0; |
} |
ADDCMD(*p, who, op, mask); |
break; |
default: |
/* |
* Add any permissions that we haven't already |
* done. |
*/ |
if (perm || (op == '=' && !equalopdone)) { |
if (op == '=') |
equalopdone = 1; |
ADDCMD(op, who, perm, mask); |
perm = 0; |
} |
if (permXbits) { |
ADDCMD('X', who, permXbits, mask); |
permXbits = 0; |
} |
goto apply; |
} |
} |
apply: if (!*p) |
break; |
if (*p != ',') |
goto getop; |
++p; |
} |
set->cmd = 0; |
#ifdef SETMODE_DEBUG |
(void)printf("Before compress_mode()\n"); |
dumpmode(saveset); |
#endif |
compress_mode(saveset); |
#ifdef SETMODE_DEBUG |
(void)printf("After compress_mode()\n"); |
dumpmode(saveset); |
#endif |
return (saveset); |
} |
static BITCMD * |
addcmd(set, op, who, oparg, mask) |
BITCMD *set; |
int oparg, who; |
int op; |
u_int mask; |
{ |
_DIAGASSERT(set != NULL); |
switch (op) { |
case '=': |
set->cmd = '-'; |
set->bits = who ? who : STANDARD_BITS; |
set++; |
op = '+'; |
/* FALLTHROUGH */ |
case '+': |
case '-': |
case 'X': |
set->cmd = op; |
set->bits = (who ? who : mask) & oparg; |
break; |
case 'u': |
case 'g': |
case 'o': |
set->cmd = op; |
if (who) { |
set->cmd2 = ((who & S_IRUSR) ? CMD2_UBITS : 0) | |
((who & S_IRGRP) ? CMD2_GBITS : 0) | |
((who & S_IROTH) ? CMD2_OBITS : 0); |
set->bits = (mode_t)~0; |
} else { |
set->cmd2 = CMD2_UBITS | CMD2_GBITS | CMD2_OBITS; |
set->bits = mask; |
} |
if (oparg == '+') |
set->cmd2 |= CMD2_SET; |
else if (oparg == '-') |
set->cmd2 |= CMD2_CLR; |
else if (oparg == '=') |
set->cmd2 |= CMD2_SET|CMD2_CLR; |
break; |
} |
return (set + 1); |
} |
#ifdef SETMODE_DEBUG |
static void |
dumpmode(set) |
BITCMD *set; |
{ |
_DIAGASSERT(set != NULL); |
for (; set->cmd; ++set) |
(void)printf("cmd: '%c' bits %04o%s%s%s%s%s%s\n", |
set->cmd, set->bits, set->cmd2 ? " cmd2:" : "", |
set->cmd2 & CMD2_CLR ? " CLR" : "", |
set->cmd2 & CMD2_SET ? " SET" : "", |
set->cmd2 & CMD2_UBITS ? " UBITS" : "", |
set->cmd2 & CMD2_GBITS ? " GBITS" : "", |
set->cmd2 & CMD2_OBITS ? " OBITS" : ""); |
} |
#endif |
/* |
* Given an array of bitcmd structures, compress by compacting consecutive |
* '+', '-' and 'X' commands into at most 3 commands, one of each. The 'u', |
* 'g' and 'o' commands continue to be separate. They could probably be |
* compacted, but it's not worth the effort. |
*/ |
static void |
compress_mode(set) |
BITCMD *set; |
{ |
BITCMD *nset; |
int setbits, clrbits, Xbits, op; |
_DIAGASSERT(set != NULL); |
for (nset = set;;) { |
/* Copy over any 'u', 'g' and 'o' commands. */ |
while ((op = nset->cmd) != '+' && op != '-' && op != 'X') { |
*set++ = *nset++; |
if (!op) |
return; |
} |
for (setbits = clrbits = Xbits = 0;; nset++) { |
if ((op = nset->cmd) == '-') { |
clrbits |= nset->bits; |
setbits &= ~nset->bits; |
Xbits &= ~nset->bits; |
} else if (op == '+') { |
setbits |= nset->bits; |
clrbits &= ~nset->bits; |
Xbits &= ~nset->bits; |
} else if (op == 'X') |
Xbits |= nset->bits & ~setbits; |
else |
break; |
} |
if (clrbits) { |
set->cmd = '-'; |
set->cmd2 = 0; |
set->bits = clrbits; |
set++; |
} |
if (setbits) { |
set->cmd = '+'; |
set->cmd2 = 0; |
set->bits = setbits; |
set++; |
} |
if (Xbits) { |
set->cmd = 'X'; |
set->cmd2 = 0; |
set->bits = Xbits; |
set++; |
} |
} |
} |
/branches/dd/uspace/app/ash/options.h |
---|
0,0 → 1,115 |
/* $NetBSD: options.h,v 1.13 1999/07/09 03:05:50 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)options.h 8.2 (Berkeley) 5/4/95 |
*/ |
struct shparam { |
int nparam; /* # of positional parameters (without $0) */ |
unsigned char malloc; /* if parameter list dynamically allocated */ |
char **p; /* parameter list */ |
int optind; /* next parameter to be processed by getopts */ |
int optoff; /* used by getopts */ |
}; |
#define eflag optlist[0].val |
#define fflag optlist[1].val |
#define Iflag optlist[2].val |
#define iflag optlist[3].val |
#define mflag optlist[4].val |
#define nflag optlist[5].val |
#define sflag optlist[6].val |
#define xflag optlist[7].val |
#define vflag optlist[8].val |
#define Vflag optlist[9].val |
#define Eflag optlist[10].val |
#define Cflag optlist[11].val |
#define aflag optlist[12].val |
#define bflag optlist[13].val |
#define uflag optlist[14].val |
#define qflag optlist[15].val |
#define NOPTS 16 |
struct optent { |
const char *name; |
const char letter; |
char val; |
}; |
#ifdef DEFINE_OPTIONS |
struct optent optlist[NOPTS] = { |
{ "errexit", 'e', 0 }, |
{ "noglob", 'f', 0 }, |
{ "ignoreeof", 'I', 0 }, |
{ "interactive",'i', 0 }, |
{ "monitor", 'm', 0 }, |
{ "noexec", 'n', 0 }, |
{ "stdin", 's', 0 }, |
{ "xtrace", 'x', 0 }, |
{ "verbose", 'v', 0 }, |
{ "vi", 'V', 0 }, |
{ "emacs", 'E', 0 }, |
{ "noclobber", 'C', 0 }, |
{ "allexport", 'a', 0 }, |
{ "notify", 'b', 0 }, |
{ "nounset", 'u', 0 }, |
{ "quietprofile", 'q', 0 }, |
}; |
#else |
extern struct optent optlist[NOPTS]; |
#endif |
extern char *minusc; /* argument to -c option */ |
extern char *arg0; /* $0 */ |
extern struct shparam shellparam; /* $@ */ |
extern char **argptr; /* argument list for builtin commands */ |
extern char *optarg; /* set by nextopt */ |
extern char *optptr; /* used by nextopt */ |
void procargs (int, char **); |
void optschanged (void); |
void setparam (char **); |
void freeparam (volatile struct shparam *); |
int shiftcmd (int, char **); |
int setcmd (int, char **); |
int getoptscmd (int, char **); |
int nextopt (const char *); |
void getoptsreset (const char *); |
/branches/dd/uspace/app/ash/mkbuiltins |
---|
0,0 → 1,100 |
#!/bin/sh - |
# $NetBSD: mkbuiltins,v 1.15 1999/07/09 03:05:50 christos Exp $ |
# |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)mkbuiltins 8.2 (Berkeley) 5/4/95 |
temp=/tmp/ka$$ |
havehist=1 |
if [ "X$1" = "X-h" ]; then |
havehist=0 |
shift |
fi |
shell=$1 |
builtins=$2 |
objdir=$3 |
havejobs=0 |
if grep '^#define JOBS[ ]*1' ${shell} > /dev/null |
then |
havejobs=1 |
fi |
exec > ${objdir}/builtins.c |
cat <<\! |
/* |
* This file was generated by the mkbuiltins program. |
*/ |
#include "shell.h" |
#include "builtins.h" |
! |
awk '/^[^#]/ {if(('$havejobs' || $2 != "-j") && ('$havehist' || $2 != "-h")) \ |
print $0}' ${builtins} | sed 's/-j//' > $temp |
awk '{ printf "int %s (int, char **);\n", $1}' $temp |
echo ' |
int (*const builtinfunc[]) (int, char **) = {' |
awk '/^[^#]/ { printf "\t%s,\n", $1}' $temp |
echo '}; |
const struct builtincmd builtincmd[] = {' |
awk '{ for (i = 2 ; i <= NF ; i++) { |
printf "\t{ \"%s\", %d },\n", $i, NR-1 |
}}' $temp |
echo ' { NULL, 0 } |
};' |
exec > ${objdir}/builtins.h |
cat <<\! |
/* |
* This file was generated by the mkbuiltins program. |
*/ |
#include <sys/cdefs.h> |
! |
tr abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWXYZ < $temp | |
awk '{ printf "#define %s %d\n", $1, NR-1}' |
echo ' |
struct builtincmd { |
const char *name; |
int code; |
}; |
extern int (*const builtinfunc[]) (int, char **); |
extern const struct builtincmd builtincmd[];' |
rm -f $temp |
/branches/dd/uspace/app/ash/fake.c |
---|
0,0 → 1,50 |
/* |
* Copyright (c) 2008 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "fake.h" |
uid_t getuid(void) |
{ |
return 0; |
} |
uid_t geteuid(void) |
{ |
return 0; |
} |
uid_t getgid(void) |
{ |
return 0; |
} |
uid_t getegid(void) |
{ |
return 0; |
} |
/branches/dd/uspace/app/ash/init.h |
---|
0,0 → 1,43 |
/* $NetBSD: init.h,v 1.8 1995/05/11 21:29:14 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)init.h 8.2 (Berkeley) 5/4/95 |
*/ |
void init (void); |
void reset (void); |
void initshellproc (void); |
/branches/dd/uspace/app/ash/fake.h |
---|
0,0 → 1,43 |
/* |
* Copyright (c) 2008 Josef Cejka |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef fake_h |
#define fake_h |
typedef int uid_t; |
uid_t getuid(void); |
uid_t geteuid(void); |
uid_t getgid(void); |
uid_t getegid(void); |
/* setjmp.h */ |
typedef int jmp_buf[6]; |
#endif |
/branches/dd/uspace/app/ash/sh.1 |
---|
0,0 → 1,1614 |
.\" $NetBSD: sh.1,v 1.40 2000/11/20 17:48:05 christos Exp $ |
.\" Copyright (c) 1991, 1993 |
.\" The Regents of the University of California. All rights reserved. |
.\" |
.\" This code is derived from software contributed to Berkeley by |
.\" Kenneth Almquist. |
.\" |
.\" Redistribution and use in source and binary forms, with or without |
.\" modification, are permitted provided that the following conditions |
.\" are met: |
.\" 1. Redistributions of source code must retain the above copyright |
.\" notice, this list of conditions and the following disclaimer. |
.\" 2. Redistributions in binary form must reproduce the above copyright |
.\" notice, this list of conditions and the following disclaimer in the |
.\" documentation and/or other materials provided with the distribution. |
.\" 3. All advertising materials mentioning features or use of this software |
.\" must display the following acknowledgement: |
.\" This product includes software developed by the University of |
.\" California, Berkeley and its contributors. |
.\" 4. Neither the name of the University nor the names of its contributors |
.\" may be used to endorse or promote products derived from this software |
.\" without specific prior written permission. |
.\" |
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
.\" SUCH DAMAGE. |
.\" |
.\" @(#)sh.1 8.6 (Berkeley) 5/4/95 |
.\" |
.Dd January 9, 1999 |
.Os |
.Dt SH 1 |
.Sh NAME |
sh \- command interpreter (shell) |
.Sh SYNOPSIS |
.Nm sh |
.Op Fl /+aCefnuvxIimqsVEbc |
.Op Fl o Ar longname |
.Bk -words |
.Op Ar target ... |
.Ek |
.Sh DESCRIPTION |
Sh is the standard command interpreter for the system. The current version |
of |
.Nm |
is in the process of being changed to conform with the |
.Tn POSIX |
1003.2 and 1003.2a specifications for the shell. This version has many |
features which make it appear similar in some respects to the Korn shell, |
but it is not a Korn shell clone (see |
.Xr ksh 1 ) . |
Only features designated by |
.Tn POSIX , |
plus a few Berkeley extensions, are being incorporated into this shell. |
We expect |
.Tn POSIX |
conformance by the time 4.4 BSD is released. This man page is not intended |
to be a tutorial or a complete specification of the shell. |
.Ss Overview |
The shell is a command that reads lines from either a file or the |
terminal, interprets them, and generally executes other commands. It is |
the program that is running when a user logs into the system (although a |
user can select a different shell with the |
.Xr chsh 1 |
command). The shell implements a language that has flow control |
constructs, a macro facility that provides a variety of features in |
addition to data storage, along with built in history and line editing |
capabilities. It incorporates many features to aid interactive use and |
has the advantage that the interpretative language is common to both |
interactive and non-interactive use (shell scripts). That is, commands |
can be typed directly to the running shell or can be put into a file and |
the file can be executed directly by the shell. |
.Ss Invocation |
If no args are present and if the standard input of the shell |
is connected to a terminal (or if the |
.Fl i |
flag is set), |
and the |
.Fl c |
option is not present, the shell is considered an interactive shell. An |
interactive shell generally prompts before each command and handles |
programming and command errors differently (as described below). When |
first starting, the shell inspects argument 0, and if it begins with a |
dash |
.Sq - , |
the shell is also considered |
a login shell. This is normally done automatically by the system |
when the user first logs in. A login shell first reads commands |
from the files |
.Pa /etc/profile |
and |
.Pa .profile |
if they exist. |
If the environment variable |
.Ev ENV |
is set on entry to a shell, or is set in the |
.Pa .profile |
of a login shell, the shell next reads |
commands from the file named in |
.Ev ENV . |
Therefore, a user should place commands that are to be executed only at |
login time in the |
.Pa .profile |
file, and commands that are executed for every shell inside the |
.Ev ENV |
file. To set the |
.Ev ENV |
variable to some file, place the following line in your |
.Pa .profile |
of your home directory |
.Pp |
.Dl ENV=$HOME/.shinit; export ENV |
.Pp |
substituting for |
.Dq .shinit |
any filename you wish. Since the |
.Ev ENV |
file is read for every invocation of the shell, including shell scripts |
and non-interactive shells, the following paradigm is useful for |
restricting commands in the |
.Ev ENV |
file to interactive invocations. Place commands within the |
.Dq case |
and |
.Dq esac |
below (these commands are described later): |
.Pp |
.Bl -item -compact -offset indent |
.It |
.Li case $- in *i*) |
.Bl -item -compact -offset indent |
.It |
.Li # commands for interactive use only |
.It |
.Li ... |
.El |
.It |
.Li esac |
.El |
.Pp |
If command line arguments besides the options have been specified, then |
the shell treats the first argument as the name of a file from which to |
read commands (a shell script), and the remaining arguments are set as the |
positional parameters of the shell ($1, $2, etc). Otherwise, the shell |
reads commands from its standard input. |
.Ss Argument List Processing |
All of the single letter options have a corresponding name that can be |
used as an argument to the |
.Fl o |
option. The set |
.Fl o |
name is provided next to the single letter option in |
the description below. Specifying a dash |
.Dq - |
turns the option on, while using a plus |
.Dq + |
disables the option. |
The following options can be set from the command line or |
with the |
.Xr set 1 |
builtin (described later). |
.Bl -tag -width aaaallexportfoo -offset indent |
.It Fl a Em allexport |
Export all variables assigned to. (UNIMPLEMENTED for 4.4alpha) |
.It Fl c |
Read commands from the command line. |
No commands will be read from the standard input. |
.It Fl C Em noclobber |
Don't overwrite existing files with |
.Dq > . |
(UNIMPLEMENTED for 4.4alpha) |
.It Fl e Em errexit |
If not interactive, exit immediately if any untested command fails. |
The exit status of a command is considered to be |
explicitly tested if the command is used to control |
an |
.Ic if , |
.Ic elif , |
.Ic while , |
or |
.Ic until ; |
or if the command is the left hand operand of an |
.Dq && |
or |
.Dq || |
operator. |
.It Fl f Em noglob |
Disable pathname expansion. |
.It Fl n Em noexec |
If not interactive, read commands but do not execute them. This is useful |
for checking the syntax of shell scripts. |
.It Fl u Em nounset |
Write a message to standard error when attempting to expand a variable |
that is not set, and if the shell is not interactive, exit immediately. |
(UNIMPLEMENTED for 4.4alpha) |
.It Fl v Em verbose |
The shell writes its input to standard error as it is read. Useful for |
debugging. |
.It Fl x Em xtrace |
Write each command to standard error (preceded |
by a |
.Sq +\ ) |
before it is executed. Useful for debugging. |
.It Fl q Em quietprofile |
If the |
.Fl v |
or |
.Fl x |
options have been set, do not apply them when reading |
initialization files, these being |
.Pa /etc/profile , |
.Pa .profile , |
and the file specified by the |
.Ev ENV |
environment variable. |
.It Fl I Em ignoreeof |
Ignore EOF's from input when interactive. |
.It Fl i Em interactive |
Force the shell to behave interactively. |
.It Fl m Em monitor |
Turn on job control (set automatically when interactive). |
.It Fl s Em stdin |
Read commands from standard input (set automatically if no file arguments |
are present). This option has no effect when set after the shell has |
already started running (i.e. with |
.Xr set 1 ) . |
.It Fl V Em vi |
Enable the built-in |
.Xr vi 1 |
command line editor (disables |
.Fl E |
if it has been set). |
.It Fl E Em emacs |
Enable the built-in |
.Xr emacs 1 |
command line editor (disables |
.Fl V |
if it has been set). |
.It Fl b Em notify |
Enable asynchronous notification of background job completion. |
(UNIMPLEMENTED for 4.4alpha) |
.El |
.Ss Lexical Structure |
The shell reads input in terms of lines from a file and breaks it up into |
words at whitespace (blanks and tabs), and at certain sequences of |
characters that are special to the shell called |
.Dq operators . |
There are two types of operators: control operators and redirection |
operators (their meaning is discussed later). Following is a list of operators: |
.Bl -ohang -offset indent |
.It "Control operators:" |
.Dl & && ( ) ; ;; | || <newline> |
.It "Redirection operator:" |
.Dl < > >| << >> <& >& <<- <> |
.El |
.Ss Quoting |
Quoting is used to remove the special meaning of certain characters or |
words to the shell, such as operators, whitespace, or keywords. There are |
three types of quoting: matched single quotes, matched double quotes, and |
backslash. |
.Ss Backslash |
A backslash preserves the literal meaning of the following |
character, with the exception of |
.Aq newline . |
A backslash preceding a |
.Aq newline |
is treated as a line continuation. |
.Ss Single Quotes |
Enclosing characters in single quotes preserves the literal meaning of all |
the characters (except single quotes, making it impossible to put |
single-quotes in a single-quoted string). |
.Ss Double Quotes |
Enclosing characters within double quotes preserves the literal |
meaning of all characters except dollarsign |
.Pq $ , |
backquote |
.Pq ` , |
and backslash |
.Pq \e . |
The backslash inside double quotes is historically weird, and serves to |
quote only the following characters: |
.Dl $ ` \*q \e <newline> . |
Otherwise it remains literal. |
.Ss Reserved Words |
Reserved words are words that have special meaning to the |
shell and are recognized at the beginning of a line and |
after a control operator. The following are reserved words: |
.Bl -column while while while while while -offset indent |
.It ! Ta elif Ta fi Ta while Ta case |
.It else Ta for Ta then Ta { Ta } |
.It do Ta done Ta until Ta if Ta esac |
.El |
.Pp |
Their meaning is discussed later. |
.Ss Aliases |
An alias is a name and corresponding value set using the |
.Xr alias 1 |
builtin command. Whenever a reserved word may occur (see above), |
and after checking for reserved words, the shell |
checks the word to see if it matches an alias. If it does, |
it replaces it in the input stream with its value. For example, |
if there is an alias called |
.Dq lf |
with the value |
.Dq "ls -F" , |
then the input: |
.Pp |
.Dl lf foobar <return> |
.Pp |
would become |
.Pp |
.Dl ls -F foobar <return> |
.Pp |
Aliases provide a convenient way for naive users to create shorthands for |
commands without having to learn how to create functions with arguments. |
They can also be used to create lexically obscure code. This use is |
discouraged. |
.Ss Commands |
The shell interprets the words it reads according to a language, the |
specification of which is outside the scope of this man page (refer to the |
BNF in the |
.Tn POSIX |
1003.2 document). Essentially though, a line is read and if the first |
word of the line (or after a control operator) is not a reserved word, |
then the shell has recognized a simple command. Otherwise, a complex |
command or some other special construct may have been recognized. |
.Ss Simple Commands |
If a simple command has been recognized, the shell performs |
the following actions: |
.Bl -enum -offset indent |
.It |
Leading words of the form |
.Dq name=value |
are stripped off and assigned to the environment of the simple command. |
Redirection operators and their arguments (as described below) are |
stripped off and saved for processing. |
.It |
The remaining words are expanded as described in |
the section called |
.Dq Expansions , |
and the first remaining word is considered the command name and the |
command is located. The remaining words are considered the arguments of |
the command. If no command name resulted, then the |
.Dq name=value |
variable assignments recognized in item 1 affect the current shell. |
.It |
Redirections are performed as described in the next section. |
.El |
.Ss Redirections |
Redirections are used to change where a command reads its input or sends |
its output. In general, redirections open, close, or duplicate an |
existing reference to a file. The overall format used for redirection is: |
.Pp |
.Dl [n] Va redir-op Ar file |
.Pp |
where |
.Va redir-op |
is one of the redirection operators mentioned previously. Following is a |
list of the possible redirections. The |
.Bq n |
is an optional number, as in |
.Sq 3 |
(not |
.Sq Bq 3 , |
that refers to a file descriptor. |
.Bl -tag -width aaabsfiles -offset indent |
.It [n] Ns > file |
Redirect standard output (or n) to file. |
.It [n] Ns >| file |
Same, but override the |
.Fl C |
option. |
.It [n] Ns >> file |
Append standard output (or n) to file. |
.It [n] Ns < file |
Redirect standard input (or n) from file. |
.It [n1] Ns <& Ns n2 |
Duplicate standard input (or n1) from file descriptor n2. |
.It [n] Ns <&- |
Close standard input (or n). |
.It [n1] Ns >& Ns n2 |
Duplicate standard output (or n1) from n2. |
.It [n] Ns >&- |
Close standard output (or n). |
.It [n] Ns <> file |
Open file for reading and writing on standard input (or n). |
.El |
.Pp |
The following redirection is often called a |
.Dq here-document . |
.Bl -item -offset indent |
.It |
.Li [n]<< delimiter |
.Dl here-doc-text... |
.Li delimiter |
.El |
.Pp |
All the text on successive lines up to the delimiter is saved away and |
made available to the command on standard input, or file descriptor n if |
it is specified. If the delimiter as specified on the initial line is |
quoted, then the here-doc-text is treated literally, otherwise the text is |
subjected to parameter expansion, command substitution, and arithmetic |
expansion (as described in the section on |
.Dq Expansions ) . |
If the operator is |
.Dq <<- |
instead of |
.Dq << , |
then leading tabs in the here-doc-text are stripped. |
.Ss Search and Execution |
There are three types of commands: shell functions, builtin commands, and |
normal programs -- and the command is searched for (by name) in that |
order. They each are executed in a different way. |
.Pp |
When a shell function is executed, all of the shell positional parameters |
(except $0, which remains unchanged) are set to the arguments of the shell |
function. The variables which are explicitly placed in the environment of |
the command (by placing assignments to them before the function name) are |
made local to the function and are set to the values given. Then the |
command given in the function definition is executed. The positional |
parameters are restored to their original values when the command |
completes. This all occurs within the current shell. |
.Pp |
Shell builtins are executed internally to the shell, without spawning a |
new process. |
.Pp |
Otherwise, if the command name doesn't match a function or builtin, the |
command is searched for as a normal program in the filesystem (as |
described in the next section). When a normal program is executed, the |
shell runs the program, passing the arguments and the environment to the |
program. If the program is not a normal executable file (i.e., if it does |
not begin with the "magic number" whose |
.Tn ASCII |
representation is "#!", so |
.Xr execve 2 |
returns |
.Er ENOEXEC |
then) the shell will interpret the program in a subshell. The child shell |
will reinitialize itself in this case, so that the effect will be as if a |
new shell had been invoked to handle the ad-hoc shell script, except that |
the location of hashed commands located in the parent shell will be |
remembered by the child. |
.Pp |
Note that previous versions of this document and the source code itself |
misleadingly and sporadically refer to a shell script without a magic |
number as a "shell procedure". |
.Ss Path Search |
.Pp |
When locating a command, the shell first looks to see if it has a shell |
function by that name. Then it looks for a builtin command by that name. |
If a builtin command is not found, one of two things happen: |
.Bl -enum |
.It |
Command names containing a slash are simply executed without performing |
any searches. |
.It |
The shell searches each entry in |
.Ev PATH |
in turn for the command. The value of the |
.Ev PATH |
variable should be a series of entries separated by colons. Each entry |
consists of a directory name. The current directory may be indicated |
implicitly by an empty directory name, or explicitly by a single period. |
.El |
.Ss Command Exit Status |
Each command has an exit status that can influence the behavior |
of other shell commands. The paradigm is that a command exits |
with zero for normal or success, and non-zero for failure, |
error, or a false indication. The man page for each command |
should indicate the various exit codes and what they mean. |
Additionally, the builtin commands return exit codes, as does |
an executed shell function. |
.Ss Complex Commands |
Complex commands are combinations of simple commands with control |
operators or reserved words, together creating a larger complex command. |
More generally, a command is one of the following: |
.Bl -bullet |
.It |
simple command |
.It |
pipeline |
.It |
list or compound-list |
.It |
compound command |
.It |
function definition |
.El |
.Pp |
Unless otherwise stated, the exit status of a command is that of the last |
simple command executed by the command. |
.Ss Pipelines |
.Pp |
A pipeline is a sequence of one or more commands separated |
by the control operator |. The standard output of all but |
the last command is connected to the standard input |
of the next command. The standard output of the last |
command is inherited from the shell, as usual. |
.Pp |
The format for a pipeline is: |
.Pp |
.Dl [!] command1 [ | command2 ...] |
.Pp |
The standard output of command1 is connected to the standard input of |
command2. The standard input, standard output, or both of a command is |
considered to be assigned by the pipeline before any redirection specified |
by redirection operators that are part of the command. |
.Pp |
If the pipeline is not in the background (discussed later), the shell |
waits for all commands to complete. |
.Pp |
If the reserved word ! does not precede the pipeline, the exit status is |
the exit status of the last command specified in the pipeline. |
Otherwise, the exit status is the logical NOT of the exit status of the |
last command. That is, if the last command returns zero, the exit status |
is 1; if the last command returns greater than zero, the exit status is |
zero. |
.Pp |
Because pipeline assignment of standard input or standard output or both |
takes place before redirection, it can be modified by redirection. For |
example: |
.Pp |
.Dl $ command1 2>&1 | command2 |
.Pp |
sends both the standard output and standard error of command1 |
to the standard input of command2. |
.Pp |
A ; or <newline> terminator causes the preceding AND-OR-list (described |
next) to be executed sequentially; a & causes asynchronous execution of |
the preceding AND-OR-list. |
.Pp |
Note that unlike some other shells, each process in the pipeline is a |
child of the invoking shell (unless it is a shell builtin, in which case |
it executes in the current shell -- but any effect it has on the |
environment is wiped). |
.Ss Background Commands -- & |
If a command is terminated by the control operator ampersand (&), the |
shell executes the command asynchronously -- that is, the shell does not |
wait for the command to finish before executing the next command. |
.Pp |
The format for running a command in background is: |
.Pp |
.Dl command1 & [command2 & ...] |
.Pp |
If the shell is not interactive, the standard input of an asynchronous |
command is set to |
.Pa /dev/null . |
.Ss Lists -- Generally Speaking |
A list is a sequence of zero or more commands separated by newlines, |
semicolons, or ampersands, and optionally terminated by one of these three |
characters. The commands in a list are executed in the order they are |
written. If command is followed by an ampersand, the shell starts the |
command and immediately proceed onto the next command; otherwise it waits |
for the command to terminate before proceeding to the next one. |
.Ss Short-Circuit List Operators |
.Dq && |
and |
.Dq || |
are AND-OR list operators. |
.Dq && |
executes the first command, and then executes the second command iff the |
exit status of the first command is zero. |
.Dq || |
is similar, but executes the second command iff the exit status of the first |
command is nonzero. |
.Dq && |
and |
.Dq || |
both have the same priority. |
.Ss Flow-Control Constructs -- if, while, for, case |
The syntax of the if command is |
.Bd -literal -offset indent |
if list |
then list |
[ elif list |
then list ] ... |
[ else list ] |
fi |
.Ed |
.Pp |
The syntax of the while command is |
.Bd -literal -offset indent |
while list |
do list |
done |
.Ed |
.Pp |
The two lists are executed repeatedly while the exit status of the |
first list is zero. The until command is similar, but has the word |
until in place of while, which causes it to |
repeat until the exit status of the first list is zero. |
.Pp |
The syntax of the for command is |
.Bd -literal -offset indent |
for variable in word... |
do list |
done |
.Ed |
.Pp |
The words are expanded, and then the list is executed repeatedly with the |
variable set to each word in turn. do and done may be replaced with |
.Dq { |
and |
.Dq } . |
.Pp |
The syntax of the break and continue command is |
.Bd -literal -offset indent |
break [ num ] |
continue [ num ] |
.Ed |
.Pp |
Break terminates the num innermost for or while loops. |
Continue continues with the next iteration of the innermost loop. |
These are implemented as builtin commands. |
.Pp |
The syntax of the case command is |
.Bd -literal -offset indent |
case word in |
pattern) list ;; |
\&... |
esac |
.Ed |
.Pp |
The pattern can actually be one or more patterns (see Shell |
Patterns described later), separated by |
.Dq \*(Ba |
characters. |
.Ss Grouping Commands Together |
Commands may be grouped by writing either |
.Pp |
.Dl (list) |
.Pp |
or |
.Pp |
.Dl { list; } |
.Pp |
The first of these executes the commands in a subshell. Builtin commands |
grouped into a (list) will not affect the current shell. The second form |
does not fork another shell so is slightly more efficient. Grouping |
commands together this way allows you to redirect their output as though |
they were one program: |
.Pp |
.Bd -literal -offset indent |
{ echo \*q hello \\c\*q ; echo \*q world" } > greeting |
.Ed |
.Pp |
.Ss Functions |
The syntax of a function definition is |
.Pp |
.Dl name ( ) command |
.Pp |
A function definition is an executable statement; when executed it |
installs a function named name and returns an exit status of zero. The |
command is normally a list enclosed between |
.Dq { |
and |
.Dq } . |
.Pp |
Variables may be declared to be local to a function by using a local |
command. This should appear as the first statement of a function, and the |
syntax is |
.Pp |
.Dl local [ variable | - ] ... |
.Pp |
Local is implemented as a builtin command. |
.Pp |
When a variable is made local, it inherits the initial value and exported |
and readonly flags from the variable with the same name in the surrounding |
scope, if there is one. Otherwise, the variable is initially unset. The |
shell uses dynamic scoping, so that if you make the variable x local to |
function f, which then calls function g, references to the variable x made |
inside g will refer to the variable x declared inside f, not to the global |
variable named x. |
.Pp |
The only special parameter than can be made local is |
.Dq - . |
Making |
.Dq - |
local any shell options that are changed via the set command inside the |
function to be restored to their original values when the function |
returns. |
.Pp |
The syntax of the return command is |
.Pp |
.Dl return [ exitstatus ] |
.Pp |
It terminates the currently executing function. Return is |
implemented as a builtin command. |
.Ss Variables and Parameters |
The shell maintains a set of parameters. A parameter denoted by a name is |
called a variable. When starting up, the shell turns all the environment |
variables into shell variables. New variables can be set using the form |
.Pp |
.Dl name=value |
.Pp |
Variables set by the user must have a name consisting solely of |
alphabetics, numerics, and underscores - the first of which must not be |
numeric. A parameter can also be denoted by a number or a special |
character as explained below. |
.Ss Positional Parameters |
A positional parameter is a parameter denoted by a number (n > 0). The |
shell sets these initially to the values of its command line arguments |
that follow the name of the shell script. The |
.Xr set 1 |
builtin can also be used to set or reset them. |
.Ss Special Parameters |
A special parameter is a parameter denoted by one of the following special |
characters. The value of the parameter is listed next to its character. |
.Bl -tag -width thinhyphena |
.It * |
Expands to the positional parameters, starting from one. When the |
expansion occurs within a double-quoted string it expands to a single |
field with the value of each parameter separated by the first character of |
the |
.Ev IFS |
variable, or by a <space> if |
.Ev IFS |
is unset. |
.It @ |
Expands to the positional parameters, starting from one. When |
the expansion occurs within double-quotes, each positional |
parameter expands as a separate argument. |
If there are no positional parameters, the |
expansion of @ generates zero arguments, even when @ is |
double-quoted. What this basically means, for example, is |
if $1 is |
.Dq abc |
and $2 is |
.Dq def ghi , |
then |
.Qq $@ |
expands to |
the two arguments: |
.Pp |
.Sm off |
.Dl \*q abc \*q \ \*q def\ ghi \*q |
.Sm on |
.It # |
Expands to the number of positional parameters. |
.It ? |
Expands to the exit status of the most recent pipeline. |
.It - (Hyphen.) |
Expands to the current option flags (the single-letter |
option names concatenated into a string) as specified on |
invocation, by the set builtin command, or implicitly |
by the shell. |
.It $ |
Expands to the process ID of the invoked shell. A subshell |
retains the same value of $ as its parent. |
.It ! |
Expands to the process ID of the most recent background |
command executed from the current shell. For a |
pipeline, the process ID is that of the last command in the |
pipeline. |
.It 0 (Zero.) |
Expands to the name of the shell or shell script. |
.El |
.Ss Word Expansions |
This clause describes the various expansions that are performed on words. |
Not all expansions are performed on every word, as explained later. |
.Pp |
Tilde expansions, parameter expansions, command substitutions, arithmetic |
expansions, and quote removals that occur within a single word expand to a |
single field. It is only field splitting or pathname expansion that can |
create multiple fields from a single word. The single exception to this |
rule is the expansion of the special parameter @ within double-quotes, as |
was described above. |
.Pp |
The order of word expansion is: |
.Bl -enum |
.It |
Tilde Expansion, Parameter Expansion, Command Substitution, |
Arithmetic Expansion (these all occur at the same time). |
.It |
Field Splitting is performed on fields |
generated by step (1) unless the |
.Ev IFS |
variable is null. |
.It |
Pathname Expansion (unless set |
.Fl f |
is in effect). |
.It |
Quote Removal. |
.El |
.Pp |
The $ character is used to introduce parameter expansion, command |
substitution, or arithmetic evaluation. |
.Ss Tilde Expansion (substituting a user's home directory) |
A word beginning with an unquoted tilde character (~) is |
subjected to tilde expansion. All the characters up to |
a slash (/) or the end of the word are treated as a username |
and are replaced with the user's home directory. If the |
username is missing (as in |
.Pa ~/foobar ) , |
the tilde is replaced with the value of the |
.Va HOME |
variable (the current user's home directory). |
.Ss Parameter Expansion |
The format for parameter expansion is as follows: |
.Pp |
.Dl ${expression} |
.Pp |
where expression consists of all characters until the matching |
.Dq } . |
Any |
.Dq } |
escaped by a backslash or within a quoted string, and characters in |
embedded arithmetic expansions, command substitutions, and variable |
expansions, are not examined in determining the matching |
.Dq } . |
.Pp |
The simplest form for parameter expansion is: |
.Pp |
.Dl ${parameter} |
.Pp |
The value, if any, of parameter is substituted. |
.Pp |
The parameter name or symbol can be enclosed in braces, which are |
optional except for positional parameters with more than one digit or |
when parameter is followed by a character that could be interpreted as |
part of the name. |
If a parameter expansion occurs inside |
double-quotes: |
.Bl -enum |
.It |
Pathname expansion is not performed on the results of the |
expansion. |
.It |
Field splitting is not performed on the results of the |
expansion, with the exception of @. |
.El |
.Pp |
In addition, a parameter expansion can be modified by using one of the |
following formats. |
.Bl -tag -width aaparameterwordaaaaa |
.It ${parameter:-word} |
Use Default Values. If parameter is unset or null, the expansion of word |
is substituted; otherwise, the value of parameter is substituted. |
.It ${parameter:=word} |
Assign Default Values. If parameter is unset or null, the expansion of |
word is assigned to parameter. In all cases, the final value of parameter |
is substituted. Only variables, not positional parameters or special |
parameters, can be assigned in this way. |
.It ${parameter:?[word]} |
Indicate Error if Null or Unset. If parameter is unset or null, the |
expansion of word (or a message indicating it is unset if word is omitted) |
is written to standard error and the shell exits with a nonzero exit |
status. Otherwise, the value of parameter is substituted. An interactive |
shell need not exit. |
.It ${parameter:+word} |
Use Alternative Value. If parameter is unset or null, null is |
substituted; otherwise, the expansion of word is substituted. |
.El |
.Pp |
In the parameter expansions shown previously, use of the colon in the |
format results in a test for a parameter that is unset or null; omission |
of the colon results in a test for a parameter that is only unset. |
.Bl -tag -width aaparameterwordaaaaa |
.It ${#parameter} |
String Length. The length in characters of |
the value of parameter. |
.El |
.Pp |
The following four varieties of parameter expansion provide for substring |
processing. In each case, pattern matching notation (see Shell Patterns), |
rather than regular expression notation, is used to evaluate the patterns. |
If parameter is * or @, the result of the expansion is unspecified. |
Enclosing the full parameter expansion string in double-quotes does not |
cause the following four varieties of pattern characters to be quoted, |
whereas quoting characters within the braces has this effect. |
.Bl -tag -width aaparameterwordaaaaa |
.It ${parameter%word} |
Remove Smallest Suffix Pattern. The word is expanded to produce a |
pattern. The parameter expansion then results in parameter, with the |
smallest portion of the suffix matched by the pattern deleted. |
.It ${parameter%%word} |
Remove Largest Suffix Pattern. The word is expanded to produce a pattern. |
The parameter expansion then results in parameter, with the largest |
portion of the suffix matched by the pattern deleted. |
.It ${parameter#word} |
Remove Smallest Prefix Pattern. The word is expanded to produce a |
pattern. The parameter expansion then results in parameter, with the |
smallest portion of the prefix matched by the pattern deleted. |
.It ${parameter##word} |
Remove Largest Prefix Pattern. The word is expanded to produce a pattern. |
The parameter expansion then results in parameter, with the largest |
portion of the prefix matched by the pattern deleted. |
.El |
.Ss Command Substitution |
Command substitution allows the output of a command to be substituted in |
place of the command name itself. Command substitution occurs when |
the command is enclosed as follows: |
.Pp |
.Dl $(command) |
.Pp |
or |
.Po |
.Dq backquoted |
version |
.Pc : |
.Pp |
.Dl `command` |
.Pp |
The shell expands the command substitution by executing command in a |
subshell environment and replacing the command substitution with the |
standard output of the command, removing sequences of one or more |
<newline>s at the end of the substitution. (Embedded <newline>s before |
the end of the output are not removed; however, during field splitting, |
they may be translated into <space>s, depending on the value of |
.Ev IFS |
and quoting that is in effect.) |
.Ss Arithmetic Expansion |
.Pp |
Arithmetic expansion provides a mechanism for evaluating an arithmetic |
expression and substituting its value. The format for arithmetic |
expansion is as follows: |
.Pp |
.Dl $((expression)) |
.Pp |
The expression is treated as if it were in double-quotes, except |
that a double-quote inside the expression is not treated specially. The |
shell expands all tokens in the expression for parameter expansion, |
command substitution, and quote removal. |
.Pp |
Next, the shell treats this as an arithmetic expression and |
substitutes the value of the expression. |
.Ss White Space Splitting (Field Splitting) |
After parameter expansion, command substitution, and |
arithmetic expansion the shell scans the results of |
expansions and substitutions that did not occur in double-quotes for |
field splitting and multiple fields can result. |
.Pp |
The shell treats each character of the |
.Ev IFS |
as a delimiter and use the delimiters to split the results of parameter |
expansion and command substitution into fields. |
.Ss Pathname Expansion (File Name Generation) |
Unless the |
.Fl f |
flag is set, file name generation is performed after word splitting is |
complete. Each word is viewed as a series of patterns, separated by |
slashes. The process of expansion replaces the word with the names of all |
existing files whose names can be formed by replacing each pattern with a |
string that matches the specified pattern. There are two restrictions on |
this: first, a pattern cannot match a string containing a slash, and |
second, a pattern cannot match a string starting with a period unless the |
first character of the pattern is a period. The next section describes the |
patterns used for both Pathname Expansion and the |
.Xr case 1 |
command. |
.Ss Shell Patterns |
A pattern consists of normal characters, which match themselves, |
and meta-characters. The meta-characters are |
.Dq ! , |
.Dq * , |
.Dq ? , |
and |
.Dq [ . |
These characters lose their special meanings if they are quoted. When |
command or variable substitution is performed and the dollar sign or back |
quotes are not double quoted, the value of the variable or the output of |
the command is scanned for these characters and they are turned into |
meta-characters. |
.Pp |
An asterisk |
.Pq Dq * |
matches any string of characters. A question mark matches any single |
character. A left bracket |
.Pq Dq \&[ |
introduces a character class. The end of |
the character class is indicated by a |
.Pq Dq \&] ; |
if the |
.Dq \&] |
is missing then the |
.Dq \&[ |
matches a |
.Dq \&[ |
rather than introducing a character class. A character class matches any |
of the characters between the square brackets. A range of characters may |
be specified using a minus sign. The character class may be complemented |
by making an exclamation point the first character of the character class. |
.Pp |
To include a |
.Dq \&] |
in a character class, make it the first character listed (after the |
.Dq \&! , |
if any). To include a minus sign, make it the first or last character listed |
.Ss Builtins |
.Pp |
This section lists the builtin commands which are builtin because they |
need to perform some operation that can't be performed by a separate |
process. In addition to these, there are several other commands that may |
be builtin for efficiency (e.g. |
.Xr printf 1 , |
.Xr echo 1 , |
.Xr test 1 , |
etc). |
.Bl -tag -width 5n |
.It : |
A null command that returns a 0 (true) exit value. |
.It \&. file |
The commands in the specified file are read and executed by the shell. |
.It alias Op Ar name Ns Op Ar "=string ..." |
If |
.Ar name=string |
is specified, the shell defines the alias |
.Ar name |
with value |
.Ar string . |
If just |
.Ar name |
is specified, the value of the alias |
.Ar name |
is printed. With no arguments, the |
.Ic alias |
builtin prints the |
names and values of all defined aliases (see |
.Ic unalias ) . |
.It bg [ Ar job ] ... |
Continue the specified jobs (or the current job if no |
jobs are given) in the background. |
.It command Ar command Ar arg... |
Execute the specified builtin command. (This is useful when you |
have a shell function with the same name as a builtin command.) |
.It cd Op Ar directory |
Switch to the specified directory (default |
.Ev $HOME ) . |
If an entry for |
.Ev CDPATH |
appears in the environment of the |
.Ic cd |
command or the shell variable |
.Ev CDPATH |
is set and the directory name does not begin with a slash, then the |
directories listed in |
.Ev CDPATH |
will be searched for the specified directory. The format of |
.Ev CDPATH |
is the same as that of |
.Ev PATH . |
In an interactive shell, the |
.Ic cd |
command will print out the name of the |
directory that it actually switched to if this is different from the name |
that the user gave. These may be different either because the |
.Ev CDPATH |
mechanism was used or because a symbolic link was crossed. |
.It eval Ar string... |
Concatenate all the arguments with spaces. Then re-parse and execute |
the command. |
.It exec Op Ar command arg... |
Unless command is omitted, the shell process is replaced with the |
specified program (which must be a real program, not a shell builtin or |
function). Any redirections on the |
.Ic exec |
command are marked as permanent, so that they are not undone when the |
.Ic exec |
command finishes. |
.It exit Op Ar exitstatus |
Terminate the shell process. If |
.Ar exitstatus |
is given it is used as the exit status of the shell; otherwise the |
exit status of the preceding command is used. |
.It export Ar name... |
.It export Fl p |
The specified names are exported so that they will appear in the |
environment of subsequent commands. The only way to un-export a variable |
is to unset it. The shell allows the value of a variable to be set at the |
same time it is exported by writing |
.Pp |
.Dl export name=value |
.Pp |
With no arguments the export command lists the names of all exported variables. |
With the |
.Fl p |
option specified the output will be formatted suitably for non-interactive use. |
.It Xo fc Op Fl e Ar editor |
.Op Ar first Op Ar last |
.Xc |
.It Xo fc Fl l |
.Op Fl nr |
.Op Ar first Op Ar last |
.Xc |
.It Xo fc Fl s Op Ar old=new |
.Op Ar first |
.Xc |
The |
.Ic fc |
builtin lists, or edits and re-executes, commands previously entered |
to an interactive shell. |
.Bl -tag -width 5n |
.It Fl e No editor |
Use the editor named by editor to edit the commands. The |
editor string is a command name, subject to search via the |
.Ev PATH |
variable. The value in the |
.Ev FCEDIT |
variable is used as a default when |
.Fl e |
is not specified. If |
.Ev FCEDIT |
is null or unset, the value of the |
.Ev EDITOR |
variable is used. If |
.Ev EDITOR |
is null or unset, |
.Xr ed 1 |
is used as the editor. |
.It Fl l No (ell) |
List the commands rather than invoking an editor on them. The commands |
are written in the sequence indicated by the first and last operands, as |
affected by |
.Fl r , |
with each command preceded by the command number. |
.It Fl n |
Suppress command numbers when listing with -l. |
.It Fl r |
Reverse the order of the commands listed (with |
.Fl l ) |
or edited (with neither |
.Fl l |
nor |
.Fl s ) . |
.It Fl s |
Re-execute the command without invoking an editor. |
.It first |
.It last |
Select the commands to list or edit. The number of previous commands that |
can be accessed are determined by the value of the |
.Ev HISTSIZE |
variable. The value of first or last or both are one of the following: |
.Bl -tag -width 5n |
.It [+]number |
A positive number representing a command number; command numbers can be |
displayed with the |
.Fl l |
option. |
.It Fl number |
A negative decimal number representing the command that was executed |
number of commands previously. For example, -1 is the immediately |
previous command. |
.El |
.It string |
A string indicating the most recently entered command that begins with |
that string. If the old=new operand is not also specified with |
.Fl s , |
the string form of the first operand cannot contain an embedded equal sign. |
.El |
.Pp |
The following environment variables affect the execution of fc: |
.Bl -tag -width HISTSIZE |
.It Ev FCEDIT |
Name of the editor to use. |
.It Ev HISTSIZE |
The number of previous commands that are accessible. |
.El |
.It fg Op Ar job |
Move the specified job or the current job to the foreground. |
.It getopts Ar optstring var |
The |
.Tn POSIX |
.Ic getopts |
command, not to be confused with the |
.Em Bell Labs |
-derived |
.Xr getopt 1 . |
.Pp |
The first argument should be a series of letters, each of which may be |
optionally followed by a colon to indicate that the option requires an |
argument. The variable specified is set to the parsed option. |
.Pp |
The |
.Ic getopts |
command deprecates the older |
.Xr getopt 1 |
utility due to its handling of arguments containing whitespace. |
.Pp |
The |
.Ic getopts |
builtin may be used to obtain options and their arguments |
from a list of parameters. When invoked, |
.Ic getopts |
places the value of the next option from the option string in the list in |
the shell variable specified by |
.Va var |
and it's index in the shell variable |
.Ev OPTIND . |
When the shell is invoked, |
.Ev OPTIND |
is initialized to 1. For each option that requires an argument, the |
.Ic getopts |
builtin will place it in the shell variable |
.Ev OPTARG . |
If an option is not allowed for in the |
.Va optstring , |
then |
.Ev OPTARG |
will be unset. |
.Pp |
.Va optstring |
is a string of recognized option letters (see |
.Xr getopt 3 ) . |
If a letter is followed by a colon, the option is expected to have an |
argument which may or may not be separated from it by white space. If an |
option character is not found where expected, |
.Ic getopts |
will set the variable |
.Va var |
to a |
.Dq ? ; |
.Ic getopts |
will then unset |
.Ev OPTARG |
and write output to standard error. By specifying a colon as the |
first character of |
.Va optstring |
all errors will be ignored. |
.Pp |
A nonzero value is returned when the last option is reached. |
If there are no remaining arguments, |
.Ic getopts |
will set |
.Va var |
to the special option, |
.Dq -- , |
otherwise, it will set |
.Va var |
to |
.Dq ? . |
.Pp |
The following code fragment shows how one might process the arguments |
for a command that can take the options |
.Op a |
and |
.Op b , |
and the option |
.Op c , |
which requires an argument. |
.Pp |
.Bd -literal -offset indent |
while getopts abc: f |
do |
case $f in |
a | b) flag=$f;; |
c) carg=$OPTARG;; |
\\?) echo $USAGE; exit 1;; |
esac |
done |
shift `expr $OPTIND - 1` |
.Ed |
.Pp |
This code will accept any of the following as equivalent: |
.Pp |
.Bd -literal -offset indent |
cmd \-acarg file file |
cmd \-a \-c arg file file |
cmd \-carg -a file file |
cmd \-a \-carg \-\- file file |
.Ed |
.It hash Fl rv Ar command... |
The shell maintains a hash table which remembers the |
locations of commands. With no arguments whatsoever, |
the |
.Ic hash |
command prints out the contents of this table. Entries which have not |
been looked at since the last |
.Ic cd |
command are marked with an asterisk; it is possible for these entries |
to be invalid. |
.Pp |
With arguments, the |
.Ic hash |
command removes the specified commands from the hash table (unless |
they are functions) and then locates them. With the |
.Fl v |
option, hash prints the locations of the commands as it finds them. The |
.Fl r |
option causes the hash command to delete all the entries in the hash table |
except for functions. |
.It jobid Op Ar job |
Print the process id's of the processes in the job. |
If the |
.Ar job |
argument is omitted, the current job is used. |
.It jobs |
This command lists out all the background processes |
which are children of the current shell process. |
.It pwd |
Print the current directory. The builtin command may |
differ from the program of the same name because the |
builtin command remembers what the current directory |
is rather than recomputing it each time. This makes |
it faster. However, if the current directory is |
renamed, the builtin version of |
.Ic pwd |
will continue to print the old name for the directory. |
.It Xo read Op Fl p Ar prompt |
.Op Fl r |
.Ar variable... |
.Xc |
The prompt is printed if the |
.Fl p |
option is specified and the standard input is a terminal. Then a line is |
read from the standard input. The trailing newline is deleted from the |
line and the line is split as described in the section on word splitting |
above, and the pieces are assigned to the variables in order. |
At least one variable must be specified. |
If there are |
more pieces than variables, the remaining pieces (along with the |
characters in |
.Ev IFS |
that separated them) are assigned to the last variable. If there are more |
variables than pieces, the remaining variables are assigned the null |
string. The |
.Ic read |
builtin will indicate success unless EOF is encountered on input, in |
which case failure is returned. |
.Pp |
By default, unless the |
.Fl r |
option is specified, the backslash |
.Dq \e |
acts as an escape character, causing the following character to be treated |
literally. If a backslash is followed by a newline, the backslash and the |
newline will be deleted. |
.It readonly Ar name... |
.It readonly Fl p |
The specified names are marked as read only, so that they cannot be |
subsequently modified or unset. The shell allows the value of a variable |
to be set at the same time it is marked read only by writing |
.Pp |
.Dl readonly name=value |
.Pp |
With no arguments the readonly command lists the names of all read only |
variables. |
With the |
.Fl p |
option specified the output will be formatted suitably for non-interactive use. |
.Pp |
.It Xo set |
.Oo { |
.Fl options | Cm +options | Cm -- } |
.Oc Ar arg... |
.Xc |
The |
.Ic set |
command performs three different functions. |
.Pp |
With no arguments, it lists the values of all shell |
variables. |
.Pp |
If options are given, it sets the specified option |
flags, or clears them as described in the section |
called |
.Sx Argument List Processing . |
.Pp |
The third use of the set command is to set the values of the shell's |
positional parameters to the specified args. To change the positional |
parameters without changing any options, use |
.Dq -- |
as the first argument to set. If no args are present, the set command |
will clear all the positional parameters (equivalent to executing |
.Dq shift $# . ) |
.It setvar Ar variable Ar value |
Assigns value to variable. (In general it is better to write |
variable=value rather than using |
.Ic setvar . |
.Ic setvar |
is intended to be used in |
functions that assign values to variables whose names are passed as |
parameters.) |
.It shift Op Ar n |
Shift the positional parameters n times. A |
.Ic shift |
sets the value of |
.Va $1 |
to the value of |
.Va $2 , |
the value of |
.Va $2 |
to the value of |
.Va $3 , |
and so on, decreasing |
the value of |
.Va $# |
by one. If there are zero positional parameters, |
.Ic shift |
does nothing. |
.It times |
Print the accumulated user and system times for the shell and for processes |
run from the shell. The return status is 0. |
.It Xo trap |
.Op Ar action |
.Ar signal... |
.Xc |
Cause the shell to parse and execute action when any of the specified |
signals are received. The signals are specified by signal number. If |
.Ar signal |
is |
.Li 0 , |
the action is executed when the shell exits. |
.Ar action |
may be null or omitted; the former causes the specified signal to be |
ignored and the latter causes the default action to be taken. When the |
shell forks off a subshell, it resets trapped (but not ignored) signals to |
the default action. The |
.Ic trap |
command has no effect on signals that were |
ignored on entry to the shell. |
.It type Op Ar name ... |
Interpret each name as a command and print the resolution of the command |
search. Possible resolutions are: |
shell keyword, alias, shell builtin, |
command, tracked alias and not found. For aliases the alias expansion is |
printed; for commands and tracked aliases the complete pathname of the |
command is printed. |
.It ulimit Xo |
.Op Fl H \*(Ba Fl S |
.Op Fl a \*(Ba Fl tfdscmlpn Op Ar value |
.Xc |
Inquire about or set the hard or soft limits on processes or set new |
limits. The choice between hard limit (which no process is allowed to |
violate, and which may not be raised once it has been lowered) and soft |
limit (which causes processes to be signaled but not necessarily killed, |
and which may be raised) is made with these flags: |
.Bl -tag -width Fl |
.It Fl H |
set or inquire about hard limits |
.It Fl S |
set or inquire about soft limits. If neither |
.Fl H |
nor |
.Fl S |
is specified, the soft limit is displayed or both limits are set. If both |
are specified, the last one wins. |
.El |
.Pp |
.Bl -tag -width Fl |
The limit to be interrogated or set, then, is chosen by specifying |
any one of these flags: |
.It Fl a |
show all the current limits |
.It Fl t |
show or set the limit on CPU time (in seconds) |
.It Fl f |
show or set the limit on the largest file that can be created |
(in 512-byte blocks) |
.It Fl d |
show or set the limit on the data segment size of a process (in kilobytes) |
.It Fl s |
show or set the limit on the stack size of a process (in kilobytes) |
.It Fl c |
show or set the limit on the largest core dump size that can be produced |
(in 512-byte blocks) |
.It Fl m |
show or set the limit on the total physical memory that can be |
in use by a process (in kilobytes) |
.It Fl l |
show or set the limit on how much memory a process can lock with |
.Xr mlock 2 |
(in kilobytes) |
.It Fl p |
show or set the limit on the number of processes this user can |
have at one time |
.It Fl n |
show or set the limit on the number files a process can have open at once |
.El |
.Pp |
If none of these is specified, it is the limit on file size that is shown |
or set. If value is specified, the limit is set to that number; otherwise |
the current limit is displayed. |
.Pp |
Limits of an arbitrary process can be displayed or set using the |
.Xr sysctl 8 |
utility. |
.Pp |
.It umask Op Ar mask |
Set the value of umask (see |
.Xr umask 2 ) |
to the specified octal value. If the argument is omitted, the umask value |
is printed. |
.It unalias Xo |
.Op Fl a |
.Op Ar name |
.Xc |
If |
.Ar name |
is specified, the shell removes that alias. If |
.Fl a |
is specified, all aliases are removed. |
.It unset Ar name... |
The specified variables and functions are unset and unexported. If a given |
name corresponds to both a variable and a function, both the variable and |
the function are unset. |
.It wait Op Ar job |
Wait for the specified job to complete and return the exit status of the |
last process in the job. If the argument is omitted, wait for all jobs to |
complete and the return an exit status of zero. |
.El |
.Ss Command Line Editing |
When |
.Nm |
is being used interactively from a terminal, the current command |
and the command history (see |
.Ic fc |
in |
.Sx Builtins ) |
can be edited using vi-mode command-line editing. This mode uses commands, |
described below, similar to a subset of those described in the vi man |
page. The command |
.Ql set -o vi |
enables vi-mode editing and place sh into vi insert mode. With vi-mode |
enabled, sh can be switched between insert mode and command mode. The |
editor is not described in full here, but will be in a later document. |
It's similar to vi: typing |
.Aq ESC |
will throw you into command VI command mode. Hitting |
.Aq return |
while in command mode will pass the line to the shell. |
.Sh ENVIRONMENT |
.Bl -tag -width MAILCHECK |
.It Ev HOME |
Set automaticly by |
.Xr login 1 |
from the user's login directory in the password file |
.Pq Xr passwd 4 . |
This environment variable also functions as the default argument for the |
cd builtin. |
.It Ev PATH |
The default search path for executables. See the above section |
.Sx Path Search . |
.It Ev CDPATH |
The search path used with the cd builtin. |
.It Ev MAIL |
The name of a mail file, that will be checked for the arrival of new mail. |
Overridden by |
.Ev MAILPATH . |
.It Ev MAILCHECK |
The frequency in seconds that the shell checks for the arrival of mail |
in the files specified by the |
.Ev MAILPATH |
or the |
.Ev MAIL |
file. If set to 0, the check will occur at each prompt. |
.It Ev MAILPATH |
A colon |
.Dq \&: |
separated list of file names, for the shell to check for incoming mail. |
This environment setting overrides the |
.Ev MAIL |
setting. There is a maximum of 10 mailboxes that can be monitored at once. |
.It Ev PS1 |
The primary prompt string, which defaults to |
.Dq $ \ , |
unless you are the superuser, in which case it defaults to |
.Dq # \ . |
.It Ev PS2 |
The secondary prompt string, which defaults to |
.Dq > \ . |
.It Ev IFS |
Input Field Separators. This is normally set to <space> <tab> and |
<newline>. See the |
.Sx White Space Splitting |
section for more details. |
.It Ev TERM |
The default terminal setting for the shell. This is inherited by |
children of the shell, and is used in the history editing modes. |
.It Ev HISTSIZE |
The number of lines in the history buffer for the shell. |
.El |
.Sh FILES |
.Bl -item -width HOMEprofilexxxx |
.It |
.Pa $HOME/.profile |
.It |
.Pa /etc/profile |
.El |
.Sh SEE ALSO |
.Xr csh 1 , |
.Xr getopt 1 , |
.Xr ksh 1 , |
.Xr login 1 , |
.Xr test 1 , |
.Xr getopt 3 , |
.Xr passwd 4 , |
.Xr profile 4 , |
.Xr environ 5 |
.Xr sysctl 8 |
.Sh HISTORY |
A |
.Nm |
command appeared in |
.At v1 . |
It was, however, unmaintainable so we wrote this one. |
.Sh EXIT STATUS |
Errors that are detected by the shell, such as a syntax error, will cause the |
shell to exit with a non-zero exit status. If the shell is not an |
interactive shell, the execution of the shell file will be aborted. Otherwise |
the shell will return the exit status of the last command executed, or |
if the exit builtin is used with a numeric argument, it will return the |
argument. |
.Sh BUGS |
Setuid shell scripts should be avoided at all costs, as they are a |
significant security risk. |
/branches/dd/uspace/app/ash/lex.yy.c |
---|
0,0 → 1,1904 |
#line 3 "lex.yy.c" |
#define YY_INT_ALIGNED short int |
/* A lexical scanner generated by flex */ |
#define FLEX_SCANNER |
#define YY_FLEX_MAJOR_VERSION 2 |
#define YY_FLEX_MINOR_VERSION 5 |
#define YY_FLEX_SUBMINOR_VERSION 33 |
#if YY_FLEX_SUBMINOR_VERSION > 0 |
#define FLEX_BETA |
#endif |
/* First, we deal with platform-specific or compiler-specific issues. */ |
/* begin standard C headers. */ |
#include <stdio.h> |
#include <string.h> |
#include <errno.h> |
#include <stdlib.h> |
/* end standard C headers. */ |
/* flex integer type definitions */ |
#ifndef FLEXINT_H |
#define FLEXINT_H |
/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */ |
#if __STDC_VERSION__ >= 199901L |
/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h, |
* if you want the limit (max/min) macros for int types. |
*/ |
#ifndef __STDC_LIMIT_MACROS |
#define __STDC_LIMIT_MACROS 1 |
#endif |
#include <inttypes.h> |
typedef int8_t flex_int8_t; |
typedef uint8_t flex_uint8_t; |
typedef int16_t flex_int16_t; |
typedef uint16_t flex_uint16_t; |
typedef int32_t flex_int32_t; |
typedef uint32_t flex_uint32_t; |
#else |
typedef signed char flex_int8_t; |
typedef short int flex_int16_t; |
typedef int flex_int32_t; |
typedef unsigned char flex_uint8_t; |
typedef unsigned short int flex_uint16_t; |
typedef unsigned int flex_uint32_t; |
#endif /* ! C99 */ |
/* Limits of integral types. */ |
#ifndef INT8_MIN |
#define INT8_MIN (-128) |
#endif |
#ifndef INT16_MIN |
#define INT16_MIN (-32767-1) |
#endif |
#ifndef INT32_MIN |
#define INT32_MIN (-2147483647-1) |
#endif |
#ifndef INT8_MAX |
#define INT8_MAX (127) |
#endif |
#ifndef INT16_MAX |
#define INT16_MAX (32767) |
#endif |
#ifndef INT32_MAX |
#define INT32_MAX (2147483647) |
#endif |
#ifndef UINT8_MAX |
#define UINT8_MAX (255U) |
#endif |
#ifndef UINT16_MAX |
#define UINT16_MAX (65535U) |
#endif |
#ifndef UINT32_MAX |
#define UINT32_MAX (4294967295U) |
#endif |
#endif /* ! FLEXINT_H */ |
#ifdef __cplusplus |
/* The "const" storage-class-modifier is valid. */ |
#define YY_USE_CONST |
#else /* ! __cplusplus */ |
#if __STDC__ |
#define YY_USE_CONST |
#endif /* __STDC__ */ |
#endif /* ! __cplusplus */ |
#ifdef YY_USE_CONST |
#define yyconst const |
#else |
#define yyconst |
#endif |
/* Returned upon end-of-file. */ |
#define YY_NULL 0 |
/* Promotes a possibly negative, possibly signed char to an unsigned |
* integer for use as an array index. If the signed char is negative, |
* we want to instead treat it as an 8-bit unsigned char, hence the |
* double cast. |
*/ |
#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c) |
/* Enter a start condition. This macro really ought to take a parameter, |
* but we do it the disgusting crufty way forced on us by the ()-less |
* definition of BEGIN. |
*/ |
#define BEGIN (yy_start) = 1 + 2 * |
/* Translate the current start state into a value that can be later handed |
* to BEGIN to return to the state. The YYSTATE alias is for lex |
* compatibility. |
*/ |
#define YY_START (((yy_start) - 1) / 2) |
#define YYSTATE YY_START |
/* Action number for EOF rule of a given start state. */ |
#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1) |
/* Special action meaning "start processing a new file". */ |
#define YY_NEW_FILE yyrestart(yyin ) |
#define YY_END_OF_BUFFER_CHAR 0 |
/* Size of default input buffer. */ |
#ifndef YY_BUF_SIZE |
#define YY_BUF_SIZE 16384 |
#endif |
/* The state buf must be large enough to hold one state per character in the main buffer. |
*/ |
#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type)) |
#ifndef YY_TYPEDEF_YY_BUFFER_STATE |
#define YY_TYPEDEF_YY_BUFFER_STATE |
typedef struct yy_buffer_state *YY_BUFFER_STATE; |
#endif |
extern int yyleng; |
extern FILE *yyin, *yyout; |
#define EOB_ACT_CONTINUE_SCAN 0 |
#define EOB_ACT_END_OF_FILE 1 |
#define EOB_ACT_LAST_MATCH 2 |
#define YY_LESS_LINENO(n) |
/* Return all but the first "n" matched characters back to the input stream. */ |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
*yy_cp = (yy_hold_char); \ |
YY_RESTORE_YY_MORE_OFFSET \ |
(yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \ |
YY_DO_BEFORE_ACTION; /* set up yytext again */ \ |
} \ |
while ( 0 ) |
#define unput(c) yyunput( c, (yytext_ptr) ) |
/* The following is because we cannot portably get our hands on size_t |
* (without autoconf's help, which isn't available because we want |
* flex-generated scanners to compile on their own). |
*/ |
#ifndef YY_TYPEDEF_YY_SIZE_T |
#define YY_TYPEDEF_YY_SIZE_T |
typedef unsigned int yy_size_t; |
#endif |
#ifndef YY_STRUCT_YY_BUFFER_STATE |
#define YY_STRUCT_YY_BUFFER_STATE |
struct yy_buffer_state |
{ |
FILE *yy_input_file; |
char *yy_ch_buf; /* input buffer */ |
char *yy_buf_pos; /* current position in input buffer */ |
/* Size of input buffer in bytes, not including room for EOB |
* characters. |
*/ |
yy_size_t yy_buf_size; |
/* Number of characters read into yy_ch_buf, not including EOB |
* characters. |
*/ |
int yy_n_chars; |
/* Whether we "own" the buffer - i.e., we know we created it, |
* and can realloc() it to grow it, and should free() it to |
* delete it. |
*/ |
int yy_is_our_buffer; |
/* Whether this is an "interactive" input source; if so, and |
* if we're using stdio for input, then we want to use getc() |
* instead of fread(), to make sure we stop fetching input after |
* each newline. |
*/ |
int yy_is_interactive; |
/* Whether we're considered to be at the beginning of a line. |
* If so, '^' rules will be active on the next match, otherwise |
* not. |
*/ |
int yy_at_bol; |
int yy_bs_lineno; /**< The line count. */ |
int yy_bs_column; /**< The column count. */ |
/* Whether to try to fill the input buffer when we reach the |
* end of it. |
*/ |
int yy_fill_buffer; |
int yy_buffer_status; |
#define YY_BUFFER_NEW 0 |
#define YY_BUFFER_NORMAL 1 |
/* When an EOF's been seen but there's still some text to process |
* then we mark the buffer as YY_EOF_PENDING, to indicate that we |
* shouldn't try reading from the input source any more. We might |
* still have a bunch of tokens to match, though, because of |
* possible backing-up. |
* |
* When we actually see the EOF, we change the status to "new" |
* (via yyrestart()), so that the user can continue scanning by |
* just pointing yyin at a new input file. |
*/ |
#define YY_BUFFER_EOF_PENDING 2 |
}; |
#endif /* !YY_STRUCT_YY_BUFFER_STATE */ |
/* Stack of input buffers. */ |
static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */ |
static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */ |
static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */ |
/* We provide macros for accessing buffer states in case in the |
* future we want to put the buffer states in a more general |
* "scanner state". |
* |
* Returns the top of the stack, or NULL. |
*/ |
#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \ |
? (yy_buffer_stack)[(yy_buffer_stack_top)] \ |
: NULL) |
/* Same as previous macro, but useful when we know that the buffer stack is not |
* NULL or when we need an lvalue. For internal use only. |
*/ |
#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)] |
/* yy_hold_char holds the character lost when yytext is formed. */ |
static char yy_hold_char; |
static int yy_n_chars; /* number of characters read into yy_ch_buf */ |
int yyleng; |
/* Points to current character in buffer. */ |
static char *yy_c_buf_p = (char *) 0; |
static int yy_init = 0; /* whether we need to initialize */ |
static int yy_start = 0; /* start state number */ |
/* Flag which is used to allow yywrap()'s to do buffer switches |
* instead of setting up a fresh yyin. A bit of a hack ... |
*/ |
static int yy_did_buffer_switch_on_eof; |
void yyrestart (FILE *input_file ); |
void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ); |
YY_BUFFER_STATE yy_create_buffer (FILE *file,int size ); |
void yy_delete_buffer (YY_BUFFER_STATE b ); |
void yy_flush_buffer (YY_BUFFER_STATE b ); |
void yypush_buffer_state (YY_BUFFER_STATE new_buffer ); |
void yypop_buffer_state (void ); |
static void yyensure_buffer_stack (void ); |
static void yy_load_buffer_state (void ); |
static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file ); |
#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER ) |
YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size ); |
YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str ); |
YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len ); |
void *yyalloc (yy_size_t ); |
void *yyrealloc (void *,yy_size_t ); |
void yyfree (void * ); |
#define yy_new_buffer yy_create_buffer |
#define yy_set_interactive(is_interactive) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){ \ |
yyensure_buffer_stack (); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
yy_create_buffer(yyin,YY_BUF_SIZE ); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \ |
} |
#define yy_set_bol(at_bol) \ |
{ \ |
if ( ! YY_CURRENT_BUFFER ){\ |
yyensure_buffer_stack (); \ |
YY_CURRENT_BUFFER_LVALUE = \ |
yy_create_buffer(yyin,YY_BUF_SIZE ); \ |
} \ |
YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \ |
} |
#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol) |
/* Begin user sect3 */ |
typedef unsigned char YY_CHAR; |
FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0; |
typedef int yy_state_type; |
extern int yylineno; |
int yylineno = 1; |
extern char *yytext; |
#define yytext_ptr yytext |
static yy_state_type yy_get_previous_state (void ); |
static yy_state_type yy_try_NUL_trans (yy_state_type current_state ); |
static int yy_get_next_buffer (void ); |
static void yy_fatal_error (yyconst char msg[] ); |
/* Done after the current pattern has been matched and before the |
* corresponding action - sets up yytext. |
*/ |
#define YY_DO_BEFORE_ACTION \ |
(yytext_ptr) = yy_bp; \ |
yyleng = (size_t) (yy_cp - yy_bp); \ |
(yy_hold_char) = *yy_cp; \ |
*yy_cp = '\0'; \ |
(yy_c_buf_p) = yy_cp; |
#define YY_NUM_RULES 26 |
#define YY_END_OF_BUFFER 27 |
/* This struct is not used in this scanner, |
but its presence is necessary. */ |
struct yy_trans_info |
{ |
flex_int32_t yy_verify; |
flex_int32_t yy_nxt; |
}; |
static yyconst flex_int16_t yy_accept[33] = |
{ 0, |
0, 0, 27, 25, 1, 1, 24, 20, 9, 3, |
4, 18, 21, 22, 19, 2, 14, 25, 12, 8, |
7, 23, 11, 6, 2, 16, 15, 10, 13, 17, |
5, 0 |
} ; |
static yyconst flex_int32_t yy_ec[256] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 2, 3, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 2, 4, 1, 1, 1, 5, 6, 1, 7, |
8, 9, 10, 1, 11, 1, 12, 13, 13, 13, |
13, 13, 13, 13, 13, 13, 13, 1, 1, 14, |
15, 16, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 17, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 18, 1, 19, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1 |
} ; |
static yyconst flex_int32_t yy_meta[20] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1 |
} ; |
static yyconst flex_int16_t yy_base[33] = |
{ 0, |
0, 0, 30, 31, 31, 31, 14, 31, 22, 31, |
31, 31, 31, 31, 31, 14, 6, 11, 7, 31, |
7, 31, 31, 31, 11, 31, 31, 31, 31, 31, |
31, 31 |
} ; |
static yyconst flex_int16_t yy_def[33] = |
{ 0, |
32, 1, 32, 32, 32, 32, 32, 32, 32, 32, |
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, |
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, |
32, 0 |
} ; |
static yyconst flex_int16_t yy_nxt[51] = |
{ 0, |
4, 5, 6, 7, 8, 9, 10, 11, 12, 13, |
14, 15, 16, 17, 18, 19, 20, 21, 22, 26, |
27, 29, 30, 25, 31, 28, 25, 24, 23, 32, |
3, 32, 32, 32, 32, 32, 32, 32, 32, 32, |
32, 32, 32, 32, 32, 32, 32, 32, 32, 32 |
} ; |
static yyconst flex_int16_t yy_chk[51] = |
{ 0, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, |
1, 1, 1, 1, 1, 1, 1, 1, 1, 17, |
17, 19, 19, 25, 21, 18, 16, 9, 7, 3, |
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, |
32, 32, 32, 32, 32, 32, 32, 32, 32, 32 |
} ; |
static yy_state_type yy_last_accepting_state; |
static char *yy_last_accepting_cpos; |
extern int yy_flex_debug; |
int yy_flex_debug = 0; |
/* The intent behind this definition is that it'll catch |
* any uses of REJECT which flex missed. |
*/ |
#define REJECT reject_used_but_not_detected |
#define yymore() yymore_used_but_not_detected |
#define YY_MORE_ADJ 0 |
#define YY_RESTORE_YY_MORE_OFFSET |
char *yytext; |
#line 1 "arith_lex.l" |
#line 2 "arith_lex.l" |
/* $NetBSD: arith_lex.l,v 1.10 1999/02/05 07:52:52 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: arith_lex.l,v 1.10 1999/02/05 07:52:52 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <unistd.h> |
#include "arith.h" |
#include "error.h" |
#include "expand.h" |
extern int yylval; |
extern char *arith_buf, *arith_startbuf; |
#undef YY_INPUT |
#define YY_INPUT(buf,result,max) \ |
result = (*buf = *arith_buf++) ? 1 : YY_NULL; |
#define YY_NO_UNPUT |
#line 530 "lex.yy.c" |
#define INITIAL 0 |
#ifndef YY_NO_UNISTD_H |
/* Special case for "unistd.h", since it is non-ANSI. We include it way |
* down here because we want the user's section 1 to have been scanned first. |
* The user has a chance to override it with an option. |
*/ |
#include <unistd.h> |
#endif |
#ifndef YY_EXTRA_TYPE |
#define YY_EXTRA_TYPE void * |
#endif |
static int yy_init_globals (void ); |
/* Macros after this point can all be overridden by user definitions in |
* section 1. |
*/ |
#ifndef YY_SKIP_YYWRAP |
#ifdef __cplusplus |
extern "C" int yywrap (void ); |
#else |
extern int yywrap (void ); |
#endif |
#endif |
static void yyunput (int c,char *buf_ptr ); |
#ifndef yytext_ptr |
static void yy_flex_strncpy (char *,yyconst char *,int ); |
#endif |
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * ); |
#endif |
#ifndef YY_NO_INPUT |
#ifdef __cplusplus |
static int yyinput (void ); |
#else |
static int input (void ); |
#endif |
#endif |
/* Amount of stuff to slurp up with each read. */ |
#ifndef YY_READ_BUF_SIZE |
#define YY_READ_BUF_SIZE 8192 |
#endif |
/* Copy whatever the last rule matched to the standard output. */ |
#ifndef ECHO |
/* This used to be an fputs(), but since the string might contain NUL's, |
* we now use fwrite(). |
*/ |
#define ECHO (void) fwrite( yytext, yyleng, 1, yyout ) |
#endif |
/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL, |
* is returned in "result". |
*/ |
#ifndef YY_INPUT |
#define YY_INPUT(buf,result,max_size) \ |
if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \ |
{ \ |
int c = '*'; \ |
size_t n; \ |
for ( n = 0; n < max_size && \ |
(c = getc( yyin )) != EOF && c != '\n'; ++n ) \ |
buf[n] = (char) c; \ |
if ( c == '\n' ) \ |
buf[n++] = (char) c; \ |
if ( c == EOF && ferror( yyin ) ) \ |
YY_FATAL_ERROR( "input in flex scanner failed" ); \ |
result = n; \ |
} \ |
else \ |
{ \ |
errno=0; \ |
while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \ |
{ \ |
if( errno != EINTR) \ |
{ \ |
YY_FATAL_ERROR( "input in flex scanner failed" ); \ |
break; \ |
} \ |
errno=0; \ |
clearerr(yyin); \ |
} \ |
}\ |
\ |
#endif |
/* No semi-colon after return; correct usage is to write "yyterminate();" - |
* we don't want an extra ';' after the "return" because that will cause |
* some compilers to complain about unreachable statements. |
*/ |
#ifndef yyterminate |
#define yyterminate() return YY_NULL |
#endif |
/* Number of entries by which start-condition stack grows. */ |
#ifndef YY_START_STACK_INCR |
#define YY_START_STACK_INCR 25 |
#endif |
/* Report a fatal error. */ |
#ifndef YY_FATAL_ERROR |
#define YY_FATAL_ERROR(msg) yy_fatal_error( msg ) |
#endif |
/* end tables serialization structures and prototypes */ |
/* Default declaration of generated scanner - a define so the user can |
* easily add parameters. |
*/ |
#ifndef YY_DECL |
#define YY_DECL_IS_OURS 1 |
extern int yylex (void); |
#define YY_DECL int yylex (void) |
#endif /* !YY_DECL */ |
/* Code executed at the beginning of each rule, after yytext and yyleng |
* have been set up. |
*/ |
#ifndef YY_USER_ACTION |
#define YY_USER_ACTION |
#endif |
/* Code executed at the end of each rule. */ |
#ifndef YY_BREAK |
#define YY_BREAK break; |
#endif |
#define YY_RULE_SETUP \ |
YY_USER_ACTION |
/** The main scanner function which does all the work. |
*/ |
YY_DECL |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp, *yy_bp; |
register int yy_act; |
#line 62 "arith_lex.l" |
#line 685 "lex.yy.c" |
if ( !(yy_init) ) |
{ |
(yy_init) = 1; |
#ifdef YY_USER_INIT |
YY_USER_INIT; |
#endif |
if ( ! (yy_start) ) |
(yy_start) = 1; /* first start state */ |
if ( ! yyin ) |
yyin = stdin; |
if ( ! yyout ) |
yyout = stdout; |
if ( ! YY_CURRENT_BUFFER ) { |
yyensure_buffer_stack (); |
YY_CURRENT_BUFFER_LVALUE = |
yy_create_buffer(yyin,YY_BUF_SIZE ); |
} |
yy_load_buffer_state( ); |
} |
while ( 1 ) /* loops until end-of-file is reached */ |
{ |
yy_cp = (yy_c_buf_p); |
/* Support of yytext. */ |
*yy_cp = (yy_hold_char); |
/* yy_bp points to the position in yy_ch_buf of the start of |
* the current run. |
*/ |
yy_bp = yy_cp; |
yy_current_state = (yy_start); |
yy_match: |
do |
{ |
register YY_CHAR yy_c = yy_ec[YY_SC_TO_UI(*yy_cp)]; |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 33 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
++yy_cp; |
} |
while ( yy_base[yy_current_state] != 31 ); |
yy_find_action: |
yy_act = yy_accept[yy_current_state]; |
if ( yy_act == 0 ) |
{ /* have to back up */ |
yy_cp = (yy_last_accepting_cpos); |
yy_current_state = (yy_last_accepting_state); |
yy_act = yy_accept[yy_current_state]; |
} |
YY_DO_BEFORE_ACTION; |
do_action: /* This label is used only to access EOF actions. */ |
switch ( yy_act ) |
{ /* beginning of action switch */ |
case 0: /* must back up */ |
/* undo the effects of YY_DO_BEFORE_ACTION */ |
*yy_cp = (yy_hold_char); |
yy_cp = (yy_last_accepting_cpos); |
yy_current_state = (yy_last_accepting_state); |
goto yy_find_action; |
case 1: |
/* rule 1 can match eol */ |
YY_RULE_SETUP |
#line 63 "arith_lex.l" |
{ ; } |
YY_BREAK |
case 2: |
YY_RULE_SETUP |
#line 64 "arith_lex.l" |
{ yylval = atol(yytext); return(ARITH_NUM); } |
YY_BREAK |
case 3: |
YY_RULE_SETUP |
#line 65 "arith_lex.l" |
{ return(ARITH_LPAREN); } |
YY_BREAK |
case 4: |
YY_RULE_SETUP |
#line 66 "arith_lex.l" |
{ return(ARITH_RPAREN); } |
YY_BREAK |
case 5: |
YY_RULE_SETUP |
#line 67 "arith_lex.l" |
{ return(ARITH_OR); } |
YY_BREAK |
case 6: |
YY_RULE_SETUP |
#line 68 "arith_lex.l" |
{ return(ARITH_AND); } |
YY_BREAK |
case 7: |
YY_RULE_SETUP |
#line 69 "arith_lex.l" |
{ return(ARITH_BOR); } |
YY_BREAK |
case 8: |
YY_RULE_SETUP |
#line 70 "arith_lex.l" |
{ return(ARITH_BXOR); } |
YY_BREAK |
case 9: |
YY_RULE_SETUP |
#line 71 "arith_lex.l" |
{ return(ARITH_BAND); } |
YY_BREAK |
case 10: |
YY_RULE_SETUP |
#line 72 "arith_lex.l" |
{ return(ARITH_EQ); } |
YY_BREAK |
case 11: |
YY_RULE_SETUP |
#line 73 "arith_lex.l" |
{ return(ARITH_NE); } |
YY_BREAK |
case 12: |
YY_RULE_SETUP |
#line 74 "arith_lex.l" |
{ return(ARITH_GT); } |
YY_BREAK |
case 13: |
YY_RULE_SETUP |
#line 75 "arith_lex.l" |
{ return(ARITH_GE); } |
YY_BREAK |
case 14: |
YY_RULE_SETUP |
#line 76 "arith_lex.l" |
{ return(ARITH_LT); } |
YY_BREAK |
case 15: |
YY_RULE_SETUP |
#line 77 "arith_lex.l" |
{ return(ARITH_LE); } |
YY_BREAK |
case 16: |
YY_RULE_SETUP |
#line 78 "arith_lex.l" |
{ return(ARITH_LSHIFT); } |
YY_BREAK |
case 17: |
YY_RULE_SETUP |
#line 79 "arith_lex.l" |
{ return(ARITH_RSHIFT); } |
YY_BREAK |
case 18: |
YY_RULE_SETUP |
#line 80 "arith_lex.l" |
{ return(ARITH_MUL); } |
YY_BREAK |
case 19: |
YY_RULE_SETUP |
#line 81 "arith_lex.l" |
{ return(ARITH_DIV); } |
YY_BREAK |
case 20: |
YY_RULE_SETUP |
#line 82 "arith_lex.l" |
{ return(ARITH_REM); } |
YY_BREAK |
case 21: |
YY_RULE_SETUP |
#line 83 "arith_lex.l" |
{ return(ARITH_ADD); } |
YY_BREAK |
case 22: |
YY_RULE_SETUP |
#line 84 "arith_lex.l" |
{ return(ARITH_SUB); } |
YY_BREAK |
case 23: |
YY_RULE_SETUP |
#line 85 "arith_lex.l" |
{ return(ARITH_BNOT); } |
YY_BREAK |
case 24: |
YY_RULE_SETUP |
#line 86 "arith_lex.l" |
{ return(ARITH_NOT); } |
YY_BREAK |
case 25: |
YY_RULE_SETUP |
#line 87 "arith_lex.l" |
{ error("arith: syntax error: \"%s\"\n", arith_startbuf); } |
YY_BREAK |
case 26: |
YY_RULE_SETUP |
#line 88 "arith_lex.l" |
ECHO; |
YY_BREAK |
#line 899 "lex.yy.c" |
case YY_STATE_EOF(INITIAL): |
yyterminate(); |
case YY_END_OF_BUFFER: |
{ |
/* Amount of text matched not including the EOB char. */ |
int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1; |
/* Undo the effects of YY_DO_BEFORE_ACTION. */ |
*yy_cp = (yy_hold_char); |
YY_RESTORE_YY_MORE_OFFSET |
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW ) |
{ |
/* We're scanning a new file or input source. It's |
* possible that this happened because the user |
* just pointed yyin at a new source and called |
* yylex(). If so, then we have to assure |
* consistency between YY_CURRENT_BUFFER and our |
* globals. Here is the right place to do so, because |
* this is the first action (other than possibly a |
* back-up) that will match for the new input source. |
*/ |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL; |
} |
/* Note that here we test for yy_c_buf_p "<=" to the position |
* of the first EOB in the buffer, since yy_c_buf_p will |
* already have been incremented past the NUL character |
* (since all states make transitions on EOB to the |
* end-of-buffer state). Contrast this with the test |
* in input(). |
*/ |
if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) |
{ /* This was really a NUL. */ |
yy_state_type yy_next_state; |
(yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text; |
yy_current_state = yy_get_previous_state( ); |
/* Okay, we're now positioned to make the NUL |
* transition. We couldn't have |
* yy_get_previous_state() go ahead and do it |
* for us because it doesn't know how to deal |
* with the possibility of jamming (and we don't |
* want to build jamming into it because then it |
* will run more slowly). |
*/ |
yy_next_state = yy_try_NUL_trans( yy_current_state ); |
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
if ( yy_next_state ) |
{ |
/* Consume the NUL. */ |
yy_cp = ++(yy_c_buf_p); |
yy_current_state = yy_next_state; |
goto yy_match; |
} |
else |
{ |
yy_cp = (yy_c_buf_p); |
goto yy_find_action; |
} |
} |
else switch ( yy_get_next_buffer( ) ) |
{ |
case EOB_ACT_END_OF_FILE: |
{ |
(yy_did_buffer_switch_on_eof) = 0; |
if ( yywrap( ) ) |
{ |
/* Note: because we've taken care in |
* yy_get_next_buffer() to have set up |
* yytext, we can now set up |
* yy_c_buf_p so that if some total |
* hoser (like flex itself) wants to |
* call the scanner after we return the |
* YY_NULL, it'll still work - another |
* YY_NULL will get returned. |
*/ |
(yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ; |
yy_act = YY_STATE_EOF(YY_START); |
goto do_action; |
} |
else |
{ |
if ( ! (yy_did_buffer_switch_on_eof) ) |
YY_NEW_FILE; |
} |
break; |
} |
case EOB_ACT_CONTINUE_SCAN: |
(yy_c_buf_p) = |
(yytext_ptr) + yy_amount_of_matched_text; |
yy_current_state = yy_get_previous_state( ); |
yy_cp = (yy_c_buf_p); |
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
goto yy_match; |
case EOB_ACT_LAST_MATCH: |
(yy_c_buf_p) = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)]; |
yy_current_state = yy_get_previous_state( ); |
yy_cp = (yy_c_buf_p); |
yy_bp = (yytext_ptr) + YY_MORE_ADJ; |
goto yy_find_action; |
} |
break; |
} |
default: |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--no action found" ); |
} /* end of action switch */ |
} /* end of scanning one token */ |
} /* end of yylex */ |
/* yy_get_next_buffer - try to read in a new buffer |
* |
* Returns a code representing an action: |
* EOB_ACT_LAST_MATCH - |
* EOB_ACT_CONTINUE_SCAN - continue scanning from current position |
* EOB_ACT_END_OF_FILE - end of file |
*/ |
static int yy_get_next_buffer (void) |
{ |
register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf; |
register char *source = (yytext_ptr); |
register int number_to_move, i; |
int ret_val; |
if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] ) |
YY_FATAL_ERROR( |
"fatal flex scanner internal error--end of buffer missed" ); |
if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 ) |
{ /* Don't try to fill the buffer, so this is an EOF. */ |
if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 ) |
{ |
/* We matched a single character, the EOB, so |
* treat this as a final EOF. |
*/ |
return EOB_ACT_END_OF_FILE; |
} |
else |
{ |
/* We matched some text prior to the EOB, first |
* process it. |
*/ |
return EOB_ACT_LAST_MATCH; |
} |
} |
/* Try to read more data. */ |
/* First move last chars to start of buffer. */ |
number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1; |
for ( i = 0; i < number_to_move; ++i ) |
*(dest++) = *(source++); |
if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING ) |
/* don't do the read, it's not guaranteed to return an EOF, |
* just force an EOF |
*/ |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0; |
else |
{ |
int num_to_read = |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1; |
while ( num_to_read <= 0 ) |
{ /* Not enough room in the buffer - grow it. */ |
/* just a shorter name for the current buffer */ |
YY_BUFFER_STATE b = YY_CURRENT_BUFFER; |
int yy_c_buf_p_offset = |
(int) ((yy_c_buf_p) - b->yy_ch_buf); |
if ( b->yy_is_our_buffer ) |
{ |
int new_size = b->yy_buf_size * 2; |
if ( new_size <= 0 ) |
b->yy_buf_size += b->yy_buf_size / 8; |
else |
b->yy_buf_size *= 2; |
b->yy_ch_buf = (char *) |
/* Include room in for 2 EOB chars. */ |
yyrealloc((void *) b->yy_ch_buf,b->yy_buf_size + 2 ); |
} |
else |
/* Can't grow it, we don't own it. */ |
b->yy_ch_buf = 0; |
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( |
"fatal error - scanner input buffer overflow" ); |
(yy_c_buf_p) = &b->yy_ch_buf[yy_c_buf_p_offset]; |
num_to_read = YY_CURRENT_BUFFER_LVALUE->yy_buf_size - |
number_to_move - 1; |
} |
if ( num_to_read > YY_READ_BUF_SIZE ) |
num_to_read = YY_READ_BUF_SIZE; |
/* Read in more data. */ |
YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]), |
(yy_n_chars), num_to_read ); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
if ( (yy_n_chars) == 0 ) |
{ |
if ( number_to_move == YY_MORE_ADJ ) |
{ |
ret_val = EOB_ACT_END_OF_FILE; |
yyrestart(yyin ); |
} |
else |
{ |
ret_val = EOB_ACT_LAST_MATCH; |
YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = |
YY_BUFFER_EOF_PENDING; |
} |
} |
else |
ret_val = EOB_ACT_CONTINUE_SCAN; |
(yy_n_chars) += number_to_move; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR; |
YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR; |
(yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0]; |
return ret_val; |
} |
/* yy_get_previous_state - get the state just before the EOB char was reached */ |
static yy_state_type yy_get_previous_state (void) |
{ |
register yy_state_type yy_current_state; |
register char *yy_cp; |
yy_current_state = (yy_start); |
for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp ) |
{ |
register YY_CHAR yy_c = (*yy_cp ? yy_ec[YY_SC_TO_UI(*yy_cp)] : 1); |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 33 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
} |
return yy_current_state; |
} |
/* yy_try_NUL_trans - try to make a transition on the NUL character |
* |
* synopsis |
* next_state = yy_try_NUL_trans( current_state ); |
*/ |
static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state ) |
{ |
register int yy_is_jam; |
register char *yy_cp = (yy_c_buf_p); |
register YY_CHAR yy_c = 1; |
if ( yy_accept[yy_current_state] ) |
{ |
(yy_last_accepting_state) = yy_current_state; |
(yy_last_accepting_cpos) = yy_cp; |
} |
while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) |
{ |
yy_current_state = (int) yy_def[yy_current_state]; |
if ( yy_current_state >= 33 ) |
yy_c = yy_meta[(unsigned int) yy_c]; |
} |
yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; |
yy_is_jam = (yy_current_state == 32); |
return yy_is_jam ? 0 : yy_current_state; |
} |
static void yyunput (int c, register char * yy_bp ) |
{ |
register char *yy_cp; |
yy_cp = (yy_c_buf_p); |
/* undo effects of setting up yytext */ |
*yy_cp = (yy_hold_char); |
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
{ /* need to shift things up to make room */ |
/* +2 for EOB chars. */ |
register int number_to_move = (yy_n_chars) + 2; |
register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[ |
YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2]; |
register char *source = |
&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]; |
while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf ) |
*--dest = *--source; |
yy_cp += (int) (dest - source); |
yy_bp += (int) (dest - source); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size; |
if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 ) |
YY_FATAL_ERROR( "flex scanner push-back overflow" ); |
} |
*--yy_cp = (char) c; |
(yytext_ptr) = yy_bp; |
(yy_hold_char) = *yy_cp; |
(yy_c_buf_p) = yy_cp; |
} |
#ifndef YY_NO_INPUT |
#ifdef __cplusplus |
static int yyinput (void) |
#else |
static int input (void) |
#endif |
{ |
int c; |
*(yy_c_buf_p) = (yy_hold_char); |
if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR ) |
{ |
/* yy_c_buf_p now points to the character we want to return. |
* If this occurs *before* the EOB characters, then it's a |
* valid NUL; if not, then we've hit the end of the buffer. |
*/ |
if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] ) |
/* This was really a NUL. */ |
*(yy_c_buf_p) = '\0'; |
else |
{ /* need more input */ |
int offset = (yy_c_buf_p) - (yytext_ptr); |
++(yy_c_buf_p); |
switch ( yy_get_next_buffer( ) ) |
{ |
case EOB_ACT_LAST_MATCH: |
/* This happens because yy_g_n_b() |
* sees that we've accumulated a |
* token and flags that we need to |
* try matching the token before |
* proceeding. But for input(), |
* there's no matching to consider. |
* So convert the EOB_ACT_LAST_MATCH |
* to EOB_ACT_END_OF_FILE. |
*/ |
/* Reset buffer status. */ |
yyrestart(yyin ); |
/*FALLTHROUGH*/ |
case EOB_ACT_END_OF_FILE: |
{ |
if ( yywrap( ) ) |
return EOF; |
if ( ! (yy_did_buffer_switch_on_eof) ) |
YY_NEW_FILE; |
#ifdef __cplusplus |
return yyinput(); |
#else |
return input(); |
#endif |
} |
case EOB_ACT_CONTINUE_SCAN: |
(yy_c_buf_p) = (yytext_ptr) + offset; |
break; |
} |
} |
} |
c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */ |
*(yy_c_buf_p) = '\0'; /* preserve yytext */ |
(yy_hold_char) = *++(yy_c_buf_p); |
return c; |
} |
#endif /* ifndef YY_NO_INPUT */ |
/** Immediately switch to a different input stream. |
* @param input_file A readable stream. |
* |
* @note This function does not reset the start condition to @c INITIAL . |
*/ |
void yyrestart (FILE * input_file ) |
{ |
if ( ! YY_CURRENT_BUFFER ){ |
yyensure_buffer_stack (); |
YY_CURRENT_BUFFER_LVALUE = |
yy_create_buffer(yyin,YY_BUF_SIZE ); |
} |
yy_init_buffer(YY_CURRENT_BUFFER,input_file ); |
yy_load_buffer_state( ); |
} |
/** Switch to a different input buffer. |
* @param new_buffer The new input buffer. |
* |
*/ |
void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer ) |
{ |
/* TODO. We should be able to replace this entire function body |
* with |
* yypop_buffer_state(); |
* yypush_buffer_state(new_buffer); |
*/ |
yyensure_buffer_stack (); |
if ( YY_CURRENT_BUFFER == new_buffer ) |
return; |
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*(yy_c_buf_p) = (yy_hold_char); |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
yy_load_buffer_state( ); |
/* We don't actually know whether we did this switch during |
* EOF (yywrap()) processing, but the only time this flag |
* is looked at is after yywrap() is called, so it's safe |
* to go ahead and always set it. |
*/ |
(yy_did_buffer_switch_on_eof) = 1; |
} |
static void yy_load_buffer_state (void) |
{ |
(yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars; |
(yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos; |
yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file; |
(yy_hold_char) = *(yy_c_buf_p); |
} |
/** Allocate and initialize an input buffer state. |
* @param file A readable stream. |
* @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE. |
* |
* @return the allocated buffer state. |
*/ |
YY_BUFFER_STATE yy_create_buffer (FILE * file, int size ) |
{ |
YY_BUFFER_STATE b; |
b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); |
if ( ! b ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); |
b->yy_buf_size = size; |
/* yy_ch_buf has to be 2 characters longer than the size given because |
* we need to put in 2 end-of-buffer characters. |
*/ |
b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 ); |
if ( ! b->yy_ch_buf ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" ); |
b->yy_is_our_buffer = 1; |
yy_init_buffer(b,file ); |
return b; |
} |
/** Destroy the buffer. |
* @param b a buffer created with yy_create_buffer() |
* |
*/ |
void yy_delete_buffer (YY_BUFFER_STATE b ) |
{ |
if ( ! b ) |
return; |
if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */ |
YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0; |
if ( b->yy_is_our_buffer ) |
yyfree((void *) b->yy_ch_buf ); |
yyfree((void *) b ); |
} |
#ifndef _UNISTD_H /* assume unistd.h has isatty() for us */ |
#ifdef __cplusplus |
extern "C" { |
#endif |
#ifdef __THROW /* this is a gnuism */ |
extern int isatty (int ) __THROW; |
#else |
extern int isatty (int ); |
#endif |
#ifdef __cplusplus |
} |
#endif |
#endif |
/* Initializes or reinitializes a buffer. |
* This function is sometimes called more than once on the same buffer, |
* such as during a yyrestart() or at EOF. |
*/ |
static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file ) |
{ |
int oerrno = errno; |
yy_flush_buffer(b ); |
b->yy_input_file = file; |
b->yy_fill_buffer = 1; |
/* If b is the current buffer, then yy_init_buffer was _probably_ |
* called from yyrestart() or through yy_get_next_buffer. |
* In that case, we don't want to reset the lineno or column. |
*/ |
if (b != YY_CURRENT_BUFFER){ |
b->yy_bs_lineno = 1; |
b->yy_bs_column = 0; |
} |
b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0; |
errno = oerrno; |
} |
/** Discard all buffered characters. On the next scan, YY_INPUT will be called. |
* @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER. |
* |
*/ |
void yy_flush_buffer (YY_BUFFER_STATE b ) |
{ |
if ( ! b ) |
return; |
b->yy_n_chars = 0; |
/* We always need two end-of-buffer characters. The first causes |
* a transition to the end-of-buffer state. The second causes |
* a jam in that state. |
*/ |
b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR; |
b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR; |
b->yy_buf_pos = &b->yy_ch_buf[0]; |
b->yy_at_bol = 1; |
b->yy_buffer_status = YY_BUFFER_NEW; |
if ( b == YY_CURRENT_BUFFER ) |
yy_load_buffer_state( ); |
} |
/** Pushes the new state onto the stack. The new state becomes |
* the current state. This function will allocate the stack |
* if necessary. |
* @param new_buffer The new state. |
* |
*/ |
void yypush_buffer_state (YY_BUFFER_STATE new_buffer ) |
{ |
if (new_buffer == NULL) |
return; |
yyensure_buffer_stack(); |
/* This block is copied from yy_switch_to_buffer. */ |
if ( YY_CURRENT_BUFFER ) |
{ |
/* Flush out information for old buffer. */ |
*(yy_c_buf_p) = (yy_hold_char); |
YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p); |
YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars); |
} |
/* Only push if top exists. Otherwise, replace top. */ |
if (YY_CURRENT_BUFFER) |
(yy_buffer_stack_top)++; |
YY_CURRENT_BUFFER_LVALUE = new_buffer; |
/* copied from yy_switch_to_buffer. */ |
yy_load_buffer_state( ); |
(yy_did_buffer_switch_on_eof) = 1; |
} |
/** Removes and deletes the top of the stack, if present. |
* The next element becomes the new top. |
* |
*/ |
void yypop_buffer_state (void) |
{ |
if (!YY_CURRENT_BUFFER) |
return; |
yy_delete_buffer(YY_CURRENT_BUFFER ); |
YY_CURRENT_BUFFER_LVALUE = NULL; |
if ((yy_buffer_stack_top) > 0) |
--(yy_buffer_stack_top); |
if (YY_CURRENT_BUFFER) { |
yy_load_buffer_state( ); |
(yy_did_buffer_switch_on_eof) = 1; |
} |
} |
/* Allocates the stack if it does not exist. |
* Guarantees space for at least one push. |
*/ |
static void yyensure_buffer_stack (void) |
{ |
int num_to_alloc; |
if (!(yy_buffer_stack)) { |
/* First allocation is just for 2 elements, since we don't know if this |
* scanner will even need a stack. We use 2 instead of 1 to avoid an |
* immediate realloc on the next call. |
*/ |
num_to_alloc = 1; |
(yy_buffer_stack) = (struct yy_buffer_state**)yyalloc |
(num_to_alloc * sizeof(struct yy_buffer_state*) |
); |
memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*)); |
(yy_buffer_stack_max) = num_to_alloc; |
(yy_buffer_stack_top) = 0; |
return; |
} |
if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){ |
/* Increase the buffer to prepare for a possible push. */ |
int grow_size = 8 /* arbitrary grow size */; |
num_to_alloc = (yy_buffer_stack_max) + grow_size; |
(yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc |
((yy_buffer_stack), |
num_to_alloc * sizeof(struct yy_buffer_state*) |
); |
/* zero only the new slots.*/ |
memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*)); |
(yy_buffer_stack_max) = num_to_alloc; |
} |
} |
/** Setup the input buffer state to scan directly from a user-specified character buffer. |
* @param base the character buffer |
* @param size the size in bytes of the character buffer |
* |
* @return the newly allocated buffer state object. |
*/ |
YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size ) |
{ |
YY_BUFFER_STATE b; |
if ( size < 2 || |
base[size-2] != YY_END_OF_BUFFER_CHAR || |
base[size-1] != YY_END_OF_BUFFER_CHAR ) |
/* They forgot to leave room for the EOB's. */ |
return 0; |
b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) ); |
if ( ! b ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" ); |
b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */ |
b->yy_buf_pos = b->yy_ch_buf = base; |
b->yy_is_our_buffer = 0; |
b->yy_input_file = 0; |
b->yy_n_chars = b->yy_buf_size; |
b->yy_is_interactive = 0; |
b->yy_at_bol = 1; |
b->yy_fill_buffer = 0; |
b->yy_buffer_status = YY_BUFFER_NEW; |
yy_switch_to_buffer(b ); |
return b; |
} |
/** Setup the input buffer state to scan a string. The next call to yylex() will |
* scan from a @e copy of @a str. |
* @param str a NUL-terminated string to scan |
* |
* @return the newly allocated buffer state object. |
* @note If you want to scan bytes that may contain NUL values, then use |
* yy_scan_bytes() instead. |
*/ |
YY_BUFFER_STATE yy_scan_string (yyconst char * yystr ) |
{ |
return yy_scan_bytes(yystr,strlen(yystr) ); |
} |
/** Setup the input buffer state to scan the given bytes. The next call to yylex() will |
* scan from a @e copy of @a bytes. |
* @param bytes the byte buffer to scan |
* @param len the number of bytes in the buffer pointed to by @a bytes. |
* |
* @return the newly allocated buffer state object. |
*/ |
YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len ) |
{ |
YY_BUFFER_STATE b; |
char *buf; |
yy_size_t n; |
int i; |
/* Get memory for full buffer, including space for trailing EOB's. */ |
n = _yybytes_len + 2; |
buf = (char *) yyalloc(n ); |
if ( ! buf ) |
YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" ); |
for ( i = 0; i < _yybytes_len; ++i ) |
buf[i] = yybytes[i]; |
buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR; |
b = yy_scan_buffer(buf,n ); |
if ( ! b ) |
YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" ); |
/* It's okay to grow etc. this buffer, and we should throw it |
* away when we're done. |
*/ |
b->yy_is_our_buffer = 1; |
return b; |
} |
#ifndef YY_EXIT_FAILURE |
#define YY_EXIT_FAILURE 2 |
#endif |
static void yy_fatal_error (yyconst char* msg ) |
{ |
(void) fprintf( stderr, "%s\n", msg ); |
exit( YY_EXIT_FAILURE ); |
} |
/* Redefine yyless() so it works in section 3 code. */ |
#undef yyless |
#define yyless(n) \ |
do \ |
{ \ |
/* Undo effects of setting up yytext. */ \ |
int yyless_macro_arg = (n); \ |
YY_LESS_LINENO(yyless_macro_arg);\ |
yytext[yyleng] = (yy_hold_char); \ |
(yy_c_buf_p) = yytext + yyless_macro_arg; \ |
(yy_hold_char) = *(yy_c_buf_p); \ |
*(yy_c_buf_p) = '\0'; \ |
yyleng = yyless_macro_arg; \ |
} \ |
while ( 0 ) |
/* Accessor methods (get/set functions) to struct members. */ |
/** Get the current line number. |
* |
*/ |
int yyget_lineno (void) |
{ |
return yylineno; |
} |
/** Get the input stream. |
* |
*/ |
FILE *yyget_in (void) |
{ |
return yyin; |
} |
/** Get the output stream. |
* |
*/ |
FILE *yyget_out (void) |
{ |
return yyout; |
} |
/** Get the length of the current token. |
* |
*/ |
int yyget_leng (void) |
{ |
return yyleng; |
} |
/** Get the current token. |
* |
*/ |
char *yyget_text (void) |
{ |
return yytext; |
} |
/** Set the current line number. |
* @param line_number |
* |
*/ |
void yyset_lineno (int line_number ) |
{ |
yylineno = line_number; |
} |
/** Set the input stream. This does not discard the current |
* input buffer. |
* @param in_str A readable stream. |
* |
* @see yy_switch_to_buffer |
*/ |
void yyset_in (FILE * in_str ) |
{ |
yyin = in_str ; |
} |
void yyset_out (FILE * out_str ) |
{ |
yyout = out_str ; |
} |
int yyget_debug (void) |
{ |
return yy_flex_debug; |
} |
void yyset_debug (int bdebug ) |
{ |
yy_flex_debug = bdebug ; |
} |
static int yy_init_globals (void) |
{ |
/* Initialization is the same as for the non-reentrant scanner. |
* This function is called from yylex_destroy(), so don't allocate here. |
*/ |
(yy_buffer_stack) = 0; |
(yy_buffer_stack_top) = 0; |
(yy_buffer_stack_max) = 0; |
(yy_c_buf_p) = (char *) 0; |
(yy_init) = 0; |
(yy_start) = 0; |
/* Defined in main.c */ |
#ifdef YY_STDINIT |
yyin = stdin; |
yyout = stdout; |
#else |
yyin = (FILE *) 0; |
yyout = (FILE *) 0; |
#endif |
/* For future reference: Set errno on error, since we are called by |
* yylex_init() |
*/ |
return 0; |
} |
/* yylex_destroy is for both reentrant and non-reentrant scanners. */ |
int yylex_destroy (void) |
{ |
/* Pop the buffer stack, destroying each element. */ |
while(YY_CURRENT_BUFFER){ |
yy_delete_buffer(YY_CURRENT_BUFFER ); |
YY_CURRENT_BUFFER_LVALUE = NULL; |
yypop_buffer_state(); |
} |
/* Destroy the stack itself. */ |
yyfree((yy_buffer_stack) ); |
(yy_buffer_stack) = NULL; |
/* Reset the globals. This is important in a non-reentrant scanner so the next time |
* yylex() is called, initialization will occur. */ |
yy_init_globals( ); |
return 0; |
} |
/* |
* Internal utility routines. |
*/ |
#ifndef yytext_ptr |
static void yy_flex_strncpy (char* s1, yyconst char * s2, int n ) |
{ |
register int i; |
for ( i = 0; i < n; ++i ) |
s1[i] = s2[i]; |
} |
#endif |
#ifdef YY_NEED_STRLEN |
static int yy_flex_strlen (yyconst char * s ) |
{ |
register int n; |
for ( n = 0; s[n]; ++n ) |
; |
return n; |
} |
#endif |
void *yyalloc (yy_size_t size ) |
{ |
return (void *) malloc( size ); |
} |
void *yyrealloc (void * ptr, yy_size_t size ) |
{ |
/* The cast to (char *) in the following accommodates both |
* implementations that use char* generic pointers, and those |
* that use void* generic pointers. It works with the latter |
* because both ANSI C and C++ allow castless assignment from |
* any pointer type to void*, and deal with argument conversions |
* as though doing an assignment. |
*/ |
return (void *) realloc( (char *) ptr, size ); |
} |
void yyfree (void * ptr ) |
{ |
free( (char *) ptr ); /* see yyrealloc() for (char *) cast */ |
} |
#define YYTABLES_NAME "yytables" |
#line 88 "arith_lex.l" |
void |
arith_lex_reset() { |
#ifdef YY_NEW_FILE |
YY_NEW_FILE; |
#endif |
} |
/branches/dd/uspace/app/ash/nodetypes |
---|
0,0 → 1,147 |
# $NetBSD: nodetypes,v 1.9 1999/02/04 16:17:39 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)nodetypes 8.2 (Berkeley) 5/4/95 |
# This file describes the nodes used in parse trees. Unindented lines |
# contain a node type followed by a structure tag. Subsequent indented |
# lines specify the fields of the structure. Several node types can share |
# the same structure, in which case the fields of the structure should be |
# specified only once. |
# |
# A field of a structure is described by the name of the field followed |
# by a type. The currently implemented types are: |
# nodeptr - a pointer to a node |
# nodelist - a pointer to a list of nodes |
# string - a pointer to a nul terminated string |
# int - an integer |
# other - any type that can be copied by assignment |
# temp - a field that doesn't have to be copied when the node is copied |
# The last two types should be followed by the text of a C declaration for |
# the field. |
NSEMI nbinary # two commands separated by a semicolon |
type int |
ch1 nodeptr # the first child |
ch2 nodeptr # the second child |
NCMD ncmd # a simple command |
type int |
backgnd int # set to run command in background |
args nodeptr # the arguments |
redirect nodeptr # list of file redirections |
NPIPE npipe # a pipeline |
type int |
backgnd int # set to run pipeline in background |
cmdlist nodelist # the commands in the pipeline |
NREDIR nredir # redirection (of a compex command) |
type int |
n nodeptr # the command |
redirect nodeptr # list of file redirections |
NBACKGND nredir # run command in background |
NSUBSHELL nredir # run command in a subshell |
NAND nbinary # the && operator |
NOR nbinary # the || operator |
NIF nif # the if statement. Elif clauses are handled |
type int # using multiple if nodes. |
test nodeptr # if test |
ifpart nodeptr # then ifpart |
elsepart nodeptr # else elsepart |
NWHILE nbinary # the while statement. First child is the test |
NUNTIL nbinary # the until statement |
NFOR nfor # the for statement |
type int |
args nodeptr # for var in args |
body nodeptr # do body; done |
var string # the for variable |
NCASE ncase # a case statement |
type int |
expr nodeptr # the word to switch on |
cases nodeptr # the list of cases (NCLIST nodes) |
NCLIST nclist # a case |
type int |
next nodeptr # the next case in list |
pattern nodeptr # list of patterns for this case |
body nodeptr # code to execute for this case |
NDEFUN narg # define a function. The "next" field contains |
# the body of the function. |
NARG narg # represents a word |
type int |
next nodeptr # next word in list |
text string # the text of the word |
backquote nodelist # list of commands in back quotes |
NTO nfile # fd> fname |
NFROM nfile # fd< fname |
NFROMTO nfile # fd<> fname |
NAPPEND nfile # fd>> fname |
NTOOV nfile # fd>| fname |
type int |
next nodeptr # next redirection in list |
fd int # file descriptor being redirected |
fname nodeptr # file name, in a NARG node |
expfname temp char *expfname # actual file name |
NTOFD ndup # fd<&dupfd |
NFROMFD ndup # fd>&dupfd |
type int |
next nodeptr # next redirection in list |
fd int # file descriptor being redirected |
dupfd int # file descriptor to duplicate |
vname nodeptr # file name if fd>&$var |
NHERE nhere # fd<<\! |
NXHERE nhere # fd<<! |
type int |
next nodeptr # next redirection in list |
fd int # file descriptor being redirected |
doc nodeptr # input to command (NARG node) |
NNOT nnot # ! command (actually pipeline) |
type int |
com nodeptr |
/branches/dd/uspace/app/ash/error.c |
---|
0,0 → 1,301 |
/* $NetBSD: error.c,v 1.23 2000/07/03 03:26:19 matt Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)error.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: error.c,v 1.23 2000/07/03 03:26:19 matt Exp $"); |
#endif |
#endif /* not lint */ |
/* |
* Errors and exceptions. |
*/ |
#include <signal.h> |
#include <stdlib.h> |
#include <unistd.h> |
#include <errno.h> |
#include "shell.h" |
#include "main.h" |
#include "options.h" |
#include "output.h" |
#include "error.h" |
#include "show.h" |
/* |
* Code to handle exceptions in C. |
*/ |
struct jmploc *handler; |
int exception; |
volatile int suppressint; |
volatile int intpending; |
char *commandname; |
static void exverror (int, const char *, va_list) |
__attribute__((__noreturn__)); |
/* |
* Called to raise an exception. Since C doesn't include exceptions, we |
* just do a longjmp to the exception handler. The type of exception is |
* stored in the global variable "exception". |
*/ |
void |
exraise(e) |
int e; |
{ |
if (handler == NULL) |
abort(); |
exception = e; |
longjmp(handler->loc, 1); |
} |
/* |
* Called from trap.c when a SIGINT is received. (If the user specifies |
* that SIGINT is to be trapped or ignored using the trap builtin, then |
* this routine is not called.) Suppressint is nonzero when interrupts |
* are held using the INTOFF macro. The call to _exit is necessary because |
* there is a short period after a fork before the signal handlers are |
* set to the appropriate value for the child. (The test for iflag is |
* just defensive programming.) |
*/ |
void |
onint() { |
sigset_t sigset; |
if (suppressint) { |
intpending++; |
return; |
} |
intpending = 0; |
sigemptyset(&sigset); |
sigprocmask(SIG_SETMASK, &sigset, NULL); |
if (rootshell && iflag) |
exraise(EXINT); |
else { |
signal(SIGINT, SIG_DFL); |
raise(SIGINT); |
} |
/* NOTREACHED */ |
} |
/* |
* Exverror is called to raise the error exception. If the first argument |
* is not NULL then error prints an error message using printf style |
* formatting. It then raises the error exception. |
*/ |
static void |
exverror(cond, msg, ap) |
int cond; |
const char *msg; |
va_list ap; |
{ |
CLEAR_PENDING_INT; |
INTOFF; |
#ifdef DEBUG |
if (msg) |
TRACE(("exverror(%d, \"%s\") pid=%d\n", cond, msg, getpid())); |
else |
TRACE(("exverror(%d, NULL) pid=%d\n", cond, getpid())); |
#endif |
if (msg) { |
if (commandname) |
outfmt(&errout, "%s: ", commandname); |
doformat(&errout, msg, ap); |
out2c('\n'); |
} |
flushall(); |
exraise(cond); |
/* NOTREACHED */ |
} |
#ifdef __STDC__ |
void |
error(const char *msg, ...) |
#else |
void |
error(va_alist) |
va_dcl |
#endif |
{ |
#ifndef __STDC__ |
const char *msg; |
#endif |
va_list ap; |
#ifdef __STDC__ |
va_start(ap, msg); |
#else |
va_start(ap); |
msg = va_arg(ap, const char *); |
#endif |
exverror(EXERROR, msg, ap); |
/* NOTREACHED */ |
va_end(ap); |
} |
#ifdef __STDC__ |
void |
exerror(int cond, const char *msg, ...) |
#else |
void |
exerror(va_alist) |
va_dcl |
#endif |
{ |
#ifndef __STDC__ |
int cond; |
const char *msg; |
#endif |
va_list ap; |
#ifdef __STDC__ |
va_start(ap, msg); |
#else |
va_start(ap); |
cond = va_arg(ap, int); |
msg = va_arg(ap, const char *); |
#endif |
exverror(cond, msg, ap); |
/* NOTREACHED */ |
va_end(ap); |
} |
/* |
* Table of error messages. |
*/ |
struct errname { |
short errcode; /* error number */ |
short action; /* operation which encountered the error */ |
const char *msg; /* text describing the error */ |
}; |
#define ALL (E_OPEN|E_CREAT|E_EXEC) |
STATIC const struct errname errormsg[] = { |
{ EINTR, ALL, "interrupted" }, |
{ EACCES, ALL, "permission denied" }, |
{ EIO, ALL, "I/O error" }, |
{ ENOENT, E_OPEN, "no such file" }, |
{ ENOENT, E_CREAT,"directory nonexistent" }, |
{ ENOENT, E_EXEC, "not found" }, |
{ ENOTDIR, E_OPEN, "no such file" }, |
{ ENOTDIR, E_CREAT,"directory nonexistent" }, |
{ ENOTDIR, E_EXEC, "not found" }, |
{ EISDIR, ALL, "is a directory" }, |
{ EEXIST, E_CREAT,"file exists" }, |
#ifdef notdef |
{ EMFILE, ALL, "too many open files" }, |
#endif |
{ ENFILE, ALL, "file table overflow" }, |
{ ENOSPC, ALL, "file system full" }, |
#ifdef EDQUOT |
{ EDQUOT, ALL, "disk quota exceeded" }, |
#endif |
#ifdef ENOSR |
{ ENOSR, ALL, "no streams resources" }, |
#endif |
{ ENXIO, ALL, "no such device or address" }, |
{ EROFS, ALL, "read-only file system" }, |
{ ETXTBSY, ALL, "text busy" }, |
#ifdef SYSV |
{ EAGAIN, E_EXEC, "not enough memory" }, |
#endif |
{ ENOMEM, ALL, "not enough memory" }, |
#ifdef ENOLINK |
{ ENOLINK, ALL, "remote access failed" }, |
#endif |
#ifdef EMULTIHOP |
{ EMULTIHOP, ALL, "remote access failed" }, |
#endif |
#ifdef ECOMM |
{ ECOMM, ALL, "remote access failed" }, |
#endif |
#ifdef ESTALE |
{ ESTALE, ALL, "remote access failed" }, |
#endif |
#ifdef ETIMEDOUT |
{ ETIMEDOUT, ALL, "remote access failed" }, |
#endif |
#ifdef ELOOP |
{ ELOOP, ALL, "symbolic link loop" }, |
#endif |
{ E2BIG, E_EXEC, "argument list too long" }, |
#ifdef ELIBACC |
{ ELIBACC, E_EXEC, "shared library missing" }, |
#endif |
{ 0, 0, NULL }, |
}; |
/* |
* Return a string describing an error. The returned string may be a |
* pointer to a static buffer that will be overwritten on the next call. |
* Action describes the operation that got the error. |
*/ |
const char * |
errmsg(e, action) |
int e; |
int action; |
{ |
struct errname const *ep; |
static char buf[12]; |
for (ep = errormsg ; ep->errcode ; ep++) { |
if (ep->errcode == e && (ep->action & action) != 0) |
return ep->msg; |
} |
fmtstr(buf, sizeof buf, "error %d", e); |
return buf; |
} |
/branches/dd/uspace/app/ash/error.h |
---|
0,0 → 1,109 |
/* $NetBSD: error.h,v 1.13 1999/07/09 03:05:49 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)error.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* |
* Types of operations (passed to the errmsg routine). |
*/ |
#define E_OPEN 01 /* opening a file */ |
#define E_CREAT 02 /* creating a file */ |
#define E_EXEC 04 /* executing a program */ |
/* |
* We enclose jmp_buf in a structure so that we can declare pointers to |
* jump locations. The global variable handler contains the location to |
* jump to when an exception occurs, and the global variable exception |
* contains a code identifying the exeception. To implement nested |
* exception handlers, the user should save the value of handler on entry |
* to an inner scope, set handler to point to a jmploc structure for the |
* inner scope, and restore handler on exit from the scope. |
*/ |
#include <setjmp.h> |
#include "fake.h" |
struct jmploc { |
jmp_buf loc; |
}; |
extern struct jmploc *handler; |
extern int exception; |
/* exceptions */ |
#define EXINT 0 /* SIGINT received */ |
#define EXERROR 1 /* a generic error */ |
#define EXSHELLPROC 2 /* execute a shell procedure */ |
#define EXEXEC 3 /* command execution failed */ |
/* |
* These macros allow the user to suspend the handling of interrupt signals |
* over a period of time. This is similar to SIGHOLD to or sigblock, but |
* much more efficient and portable. (But hacking the kernel is so much |
* more fun than worrying about efficiency and portability. :-)) |
*/ |
extern volatile int suppressint; |
extern volatile int intpending; |
extern char *commandname; /* name of command--printed on error */ |
#define INTOFF suppressint++ |
#define INTON { if (--suppressint == 0 && intpending) onint(); } |
#define FORCEINTON {suppressint = 0; if (intpending) onint();} |
#define CLEAR_PENDING_INT intpending = 0 |
#define int_pending() intpending |
void exraise (int) __attribute__((__noreturn__)); |
void onint (void); |
void error (const char *, ...) __attribute__((__noreturn__)); |
void exerror (int, const char *, ...) __attribute__((__noreturn__)); |
const char *errmsg (int, int); |
/* |
* BSD setjmp saves the signal mask, which violates ANSI C and takes time, |
* so we use _setjmp instead. |
*/ |
#if defined(BSD) && !defined(__SVR4) && !defined(__GLIBC__) |
#define setjmp(jmploc) _setjmp(jmploc) |
#define longjmp(jmploc, val) _longjmp(jmploc, val) |
#endif |
/branches/dd/uspace/app/ash/machdep.h |
---|
0,0 → 1,53 |
/* $NetBSD: machdep.h,v 1.8 1995/05/11 21:29:21 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)machdep.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* |
* Most machines require the value returned from malloc to be aligned |
* in some way. The following macro will get this right on many machines. |
*/ |
#ifndef ALIGN |
union align { |
int i; |
char *cp; |
}; |
#define ALIGN(nbytes) (((nbytes) + sizeof(union align) - 1) & ~(sizeof(union align) - 1)) |
#endif |
/branches/dd/uspace/app/ash/TOUR |
---|
0,0 → 1,357 |
# $NetBSD: TOUR,v 1.8 1996/10/16 14:24:56 christos Exp $ |
# @(#)TOUR 8.1 (Berkeley) 5/31/93 |
NOTE -- This is the original TOUR paper distributed with ash and |
does not represent the current state of the shell. It is provided anyway |
since it provides helpful information for how the shell is structured, |
but be warned that things have changed -- the current shell is |
still under development. |
================================================================ |
A Tour through Ash |
Copyright 1989 by Kenneth Almquist. |
DIRECTORIES: The subdirectory bltin contains commands which can |
be compiled stand-alone. The rest of the source is in the main |
ash directory. |
SOURCE CODE GENERATORS: Files whose names begin with "mk" are |
programs that generate source code. A complete list of these |
programs is: |
program intput files generates |
------- ------------ --------- |
mkbuiltins builtins builtins.h builtins.c |
mkinit *.c init.c |
mknodes nodetypes nodes.h nodes.c |
mksignames - signames.h signames.c |
mksyntax - syntax.h syntax.c |
mktokens - token.h |
bltin/mkexpr unary_op binary_op operators.h operators.c |
There are undoubtedly too many of these. Mkinit searches all the |
C source files for entries looking like: |
INIT { |
x = 1; /* executed during initialization */ |
} |
RESET { |
x = 2; /* executed when the shell does a longjmp |
back to the main command loop */ |
} |
SHELLPROC { |
x = 3; /* executed when the shell runs a shell procedure */ |
} |
It pulls this code out into routines which are when particular |
events occur. The intent is to improve modularity by isolating |
the information about which modules need to be explicitly |
initialized/reset within the modules themselves. |
Mkinit recognizes several constructs for placing declarations in |
the init.c file. |
INCLUDE "file.h" |
includes a file. The storage class MKINIT makes a declaration |
available in the init.c file, for example: |
MKINIT int funcnest; /* depth of function calls */ |
MKINIT alone on a line introduces a structure or union declara- |
tion: |
MKINIT |
struct redirtab { |
short renamed[10]; |
}; |
Preprocessor #define statements are copied to init.c without any |
special action to request this. |
INDENTATION: The ash source is indented in multiples of six |
spaces. The only study that I have heard of on the subject con- |
cluded that the optimal amount to indent is in the range of four |
to six spaces. I use six spaces since it is not too big a jump |
from the widely used eight spaces. If you really hate six space |
indentation, use the adjind (source included) program to change |
it to something else. |
EXCEPTIONS: Code for dealing with exceptions appears in |
exceptions.c. The C language doesn't include exception handling, |
so I implement it using setjmp and longjmp. The global variable |
exception contains the type of exception. EXERROR is raised by |
calling error. EXINT is an interrupt. EXSHELLPROC is an excep- |
tion which is raised when a shell procedure is invoked. The pur- |
pose of EXSHELLPROC is to perform the cleanup actions associated |
with other exceptions. After these cleanup actions, the shell |
can interpret a shell procedure itself without exec'ing a new |
copy of the shell. |
INTERRUPTS: In an interactive shell, an interrupt will cause an |
EXINT exception to return to the main command loop. (Exception: |
EXINT is not raised if the user traps interrupts using the trap |
command.) The INTOFF and INTON macros (defined in exception.h) |
provide uninterruptable critical sections. Between the execution |
of INTOFF and the execution of INTON, interrupt signals will be |
held for later delivery. INTOFF and INTON can be nested. |
MEMALLOC.C: Memalloc.c defines versions of malloc and realloc |
which call error when there is no memory left. It also defines a |
stack oriented memory allocation scheme. Allocating off a stack |
is probably more efficient than allocation using malloc, but the |
big advantage is that when an exception occurs all we have to do |
to free up the memory in use at the time of the exception is to |
restore the stack pointer. The stack is implemented using a |
linked list of blocks. |
STPUTC: If the stack were contiguous, it would be easy to store |
strings on the stack without knowing in advance how long the |
string was going to be: |
p = stackptr; |
*p++ = c; /* repeated as many times as needed */ |
stackptr = p; |
The folloing three macros (defined in memalloc.h) perform these |
operations, but grow the stack if you run off the end: |
STARTSTACKSTR(p); |
STPUTC(c, p); /* repeated as many times as needed */ |
grabstackstr(p); |
We now start a top-down look at the code: |
MAIN.C: The main routine performs some initialization, executes |
the user's profile if necessary, and calls cmdloop. Cmdloop is |
repeatedly parses and executes commands. |
OPTIONS.C: This file contains the option processing code. It is |
called from main to parse the shell arguments when the shell is |
invoked, and it also contains the set builtin. The -i and -j op- |
tions (the latter turns on job control) require changes in signal |
handling. The routines setjobctl (in jobs.c) and setinteractive |
(in trap.c) are called to handle changes to these options. |
PARSING: The parser code is all in parser.c. A recursive des- |
cent parser is used. Syntax tables (generated by mksyntax) are |
used to classify characters during lexical analysis. There are |
three tables: one for normal use, one for use when inside single |
quotes, and one for use when inside double quotes. The tables |
are machine dependent because they are indexed by character vari- |
ables and the range of a char varies from machine to machine. |
PARSE OUTPUT: The output of the parser consists of a tree of |
nodes. The various types of nodes are defined in the file node- |
types. |
Nodes of type NARG are used to represent both words and the con- |
tents of here documents. An early version of ash kept the con- |
tents of here documents in temporary files, but keeping here do- |
cuments in memory typically results in significantly better per- |
formance. It would have been nice to make it an option to use |
temporary files for here documents, for the benefit of small |
machines, but the code to keep track of when to delete the tem- |
porary files was complex and I never fixed all the bugs in it. |
(AT&T has been maintaining the Bourne shell for more than ten |
years, and to the best of my knowledge they still haven't gotten |
it to handle temporary files correctly in obscure cases.) |
The text field of a NARG structure points to the text of the |
word. The text consists of ordinary characters and a number of |
special codes defined in parser.h. The special codes are: |
CTLVAR Variable substitution |
CTLENDVAR End of variable substitution |
CTLBACKQ Command substitution |
CTLBACKQ|CTLQUOTE Command substitution inside double quotes |
CTLESC Escape next character |
A variable substitution contains the following elements: |
CTLVAR type name '=' [ alternative-text CTLENDVAR ] |
The type field is a single character specifying the type of sub- |
stitution. The possible types are: |
VSNORMAL $var |
VSMINUS ${var-text} |
VSMINUS|VSNUL ${var:-text} |
VSPLUS ${var+text} |
VSPLUS|VSNUL ${var:+text} |
VSQUESTION ${var?text} |
VSQUESTION|VSNUL ${var:?text} |
VSASSIGN ${var=text} |
VSASSIGN|VSNUL ${var=text} |
In addition, the type field will have the VSQUOTE flag set if the |
variable is enclosed in double quotes. The name of the variable |
comes next, terminated by an equals sign. If the type is not |
VSNORMAL, then the text field in the substitution follows, ter- |
minated by a CTLENDVAR byte. |
Commands in back quotes are parsed and stored in a linked list. |
The locations of these commands in the string are indicated by |
CTLBACKQ and CTLBACKQ+CTLQUOTE characters, depending upon whether |
the back quotes were enclosed in double quotes. |
The character CTLESC escapes the next character, so that in case |
any of the CTL characters mentioned above appear in the input, |
they can be passed through transparently. CTLESC is also used to |
escape '*', '?', '[', and '!' characters which were quoted by the |
user and thus should not be used for file name generation. |
CTLESC characters have proved to be particularly tricky to get |
right. In the case of here documents which are not subject to |
variable and command substitution, the parser doesn't insert any |
CTLESC characters to begin with (so the contents of the text |
field can be written without any processing). Other here docu- |
ments, and words which are not subject to splitting and file name |
generation, have the CTLESC characters removed during the vari- |
able and command substitution phase. Words which are subject |
splitting and file name generation have the CTLESC characters re- |
moved as part of the file name phase. |
EXECUTION: Command execution is handled by the following files: |
eval.c The top level routines. |
redir.c Code to handle redirection of input and output. |
jobs.c Code to handle forking, waiting, and job control. |
exec.c Code to to path searches and the actual exec sys call. |
expand.c Code to evaluate arguments. |
var.c Maintains the variable symbol table. Called from expand.c. |
EVAL.C: Evaltree recursively executes a parse tree. The exit |
status is returned in the global variable exitstatus. The alter- |
native entry evalbackcmd is called to evaluate commands in back |
quotes. It saves the result in memory if the command is a buil- |
tin; otherwise it forks off a child to execute the command and |
connects the standard output of the child to a pipe. |
JOBS.C: To create a process, you call makejob to return a job |
structure, and then call forkshell (passing the job structure as |
an argument) to create the process. Waitforjob waits for a job |
to complete. These routines take care of process groups if job |
control is defined. |
REDIR.C: Ash allows file descriptors to be redirected and then |
restored without forking off a child process. This is accom- |
plished by duplicating the original file descriptors. The redir- |
tab structure records where the file descriptors have be dupli- |
cated to. |
EXEC.C: The routine find_command locates a command, and enters |
the command in the hash table if it is not already there. The |
third argument specifies whether it is to print an error message |
if the command is not found. (When a pipeline is set up, |
find_command is called for all the commands in the pipeline be- |
fore any forking is done, so to get the commands into the hash |
table of the parent process. But to make command hashing as |
transparent as possible, we silently ignore errors at that point |
and only print error messages if the command cannot be found |
later.) |
The routine shellexec is the interface to the exec system call. |
EXPAND.C: Arguments are processed in three passes. The first |
(performed by the routine argstr) performs variable and command |
substitution. The second (ifsbreakup) performs word splitting |
and the third (expandmeta) performs file name generation. If the |
"/u" directory is simulated, then when "/u/username" is replaced |
by the user's home directory, the flag "didudir" is set. This |
tells the cd command that it should print out the directory name, |
just as it would if the "/u" directory were implemented using |
symbolic links. |
VAR.C: Variables are stored in a hash table. Probably we should |
switch to extensible hashing. The variable name is stored in the |
same string as the value (using the format "name=value") so that |
no string copying is needed to create the environment of a com- |
mand. Variables which the shell references internally are preal- |
located so that the shell can reference the values of these vari- |
ables without doing a lookup. |
When a program is run, the code in eval.c sticks any environment |
variables which precede the command (as in "PATH=xxx command") in |
the variable table as the simplest way to strip duplicates, and |
then calls "environment" to get the value of the environment. |
There are two consequences of this. First, if an assignment to |
PATH precedes the command, the value of PATH before the assign- |
ment must be remembered and passed to shellexec. Second, if the |
program turns out to be a shell procedure, the strings from the |
environment variables which preceded the command must be pulled |
out of the table and replaced with strings obtained from malloc, |
since the former will automatically be freed when the stack (see |
the entry on memalloc.c) is emptied. |
BUILTIN COMMANDS: The procedures for handling these are scat- |
tered throughout the code, depending on which location appears |
most appropriate. They can be recognized because their names al- |
ways end in "cmd". The mapping from names to procedures is |
specified in the file builtins, which is processed by the mkbuil- |
tins command. |
A builtin command is invoked with argc and argv set up like a |
normal program. A builtin command is allowed to overwrite its |
arguments. Builtin routines can call nextopt to do option pars- |
ing. This is kind of like getopt, but you don't pass argc and |
argv to it. Builtin routines can also call error. This routine |
normally terminates the shell (or returns to the main command |
loop if the shell is interactive), but when called from a builtin |
command it causes the builtin command to terminate with an exit |
status of 2. |
The directory bltins contains commands which can be compiled in- |
dependently but can also be built into the shell for efficiency |
reasons. The makefile in this directory compiles these programs |
in the normal fashion (so that they can be run regardless of |
whether the invoker is ash), but also creates a library named |
bltinlib.a which can be linked with ash. The header file bltin.h |
takes care of most of the differences between the ash and the |
stand-alone environment. The user should call the main routine |
"main", and #define main to be the name of the routine to use |
when the program is linked into ash. This #define should appear |
before bltin.h is included; bltin.h will #undef main if the pro- |
gram is to be compiled stand-alone. |
CD.C: This file defines the cd and pwd builtins. The pwd com- |
mand runs /bin/pwd the first time it is invoked (unless the user |
has already done a cd to an absolute pathname), but then |
remembers the current directory and updates it when the cd com- |
mand is run, so subsequent pwd commands run very fast. The main |
complication in the cd command is in the docd command, which |
resolves symbolic links into actual names and informs the user |
where the user ended up if he crossed a symbolic link. |
SIGNALS: Trap.c implements the trap command. The routine set- |
signal figures out what action should be taken when a signal is |
received and invokes the signal system call to set the signal ac- |
tion appropriately. When a signal that a user has set a trap for |
is caught, the routine "onsig" sets a flag. The routine dotrap |
is called at appropriate points to actually handle the signal. |
When an interrupt is caught and no trap has been set for that |
signal, the routine "onint" in error.c is called. |
OUTPUT: Ash uses it's own output routines. There are three out- |
put structures allocated. "Output" represents the standard out- |
put, "errout" the standard error, and "memout" contains output |
which is to be stored in memory. This last is used when a buil- |
tin command appears in backquotes, to allow its output to be col- |
lected without doing any I/O through the UNIX operating system. |
The variables out1 and out2 normally point to output and errout, |
respectively, but they are set to point to memout when appropri- |
ate inside backquotes. |
INPUT: The basic input routine is pgetc, which reads from the |
current input file. There is a stack of input files; the current |
input file is the top file on this stack. The code allows the |
input to come from a string rather than a file. (This is for the |
-c option and the "." and eval builtin commands.) The global |
variable plinno is saved and restored when files are pushed and |
popped from the stack. The parser routines store the number of |
the current line in this variable. |
DEBUGGING: If DEBUG is defined in shell.h, then the shell will |
write debugging information to the file $HOME/trace. Most of |
this is done using the TRACE macro, which takes a set of printf |
arguments inside two sets of parenthesis. Example: |
"TRACE(("n=%d0, n))". The double parenthesis are necessary be- |
cause the preprocessor can't handle functions with a variable |
number of arguments. Defining DEBUG also causes the shell to |
generate a core dump if it is sent a quit signal. The tracing |
code is in show.c. |
/branches/dd/uspace/app/ash/hetio.c |
---|
0,0 → 1,378 |
/* |
* Termios command line History and Editting for NetBSD sh (ash) |
* Copyright (c) 1999 |
* Main code: Adam Rogoyski <rogoyski@cs.utexas.edu> |
* Etc: Dave Cinege <dcinege@psychosis.com> |
* |
* You may use this code as you wish, so long as the original author(s) |
* are attributed in any redistributions of the source code. |
* This code is 'as is' with no warranty. |
* This code may safely be consumed by a BSD or GPL license. |
* |
* v 0.5 19990328 Initial release |
* |
* Future plans: Simple file and path name completion. (like BASH) |
* |
*/ |
/* |
Usage and Known bugs: |
Terminal key codes are not extensive, and more will probably |
need to be added. This version was created on Debian GNU/Linux 2.x. |
Delete, Backspace, Home, End, and the arrow keys were tested |
to work in an Xterm and console. Ctrl-A also works as Home. |
Ctrl-E also works as End. The binary size increase is <3K. |
Editting will not display correctly for lines greater then the |
terminal width. (more then one line.) However, history will. |
*/ |
#include <stdio.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <string.h> |
#include <termios.h> |
#include <ctype.h> |
#include <sys/ioctl.h> |
#include "input.h" |
#include "output.h" |
#ifdef HETIO |
#include "hetio.h" |
#define MAX_HISTORY 15 /* Maximum length of the linked list for the command line history */ |
#define ESC 27 |
#define DEL 127 |
static struct history *his_front = NULL; /* First element in command line list */ |
static struct history *his_end = NULL; /* Last element in command line list */ |
static struct termios old_term, new_term; /* Current termio and the previous termio before starting ash */ |
static int history_counter = 0; /* Number of commands in history list */ |
static int reset_term = 0; /* Set to true if the terminal needs to be reset upon exit */ |
//static int hetio_inter = 0; |
int hetio_inter = 0; |
struct history |
{ |
char *s; |
struct history *p; |
struct history *n; |
}; |
void input_delete (int); |
void input_home (int *); |
void input_end (int *, int); |
void input_backspace (int *, int *); |
void hetio_init(void) |
{ |
hetio_inter = 1; |
} |
void hetio_reset_term(void) |
{ |
if (reset_term) |
tcsetattr(1, TCSANOW, &old_term); |
} |
void setIO(struct termios *new, struct termios *old) /* Set terminal IO to canonical mode, and save old term settings. */ |
{ |
tcgetattr(0, old); |
memcpy(new, old, sizeof(*new)); |
new->c_cc[VMIN] = 1; |
new->c_cc[VTIME] = 0; |
new->c_lflag &= ~ICANON; /* unbuffered input */ |
new->c_lflag &= ~ECHO; |
tcsetattr(0, TCSANOW, new); |
} |
void input_home(int *cursor) /* Command line input routines */ |
{ |
while (*cursor > 0) { |
out1c('\b'); |
--*cursor; |
} |
flushout(&output); |
} |
void input_delete(int cursor) |
{ |
int j = 0; |
memmove(parsenextc + cursor, parsenextc + cursor + 1, |
BUFSIZ - cursor - 1); |
for (j = cursor; j < (BUFSIZ - 1); j++) { |
if (!*(parsenextc + j)) |
break; |
else |
out1c(*(parsenextc + j)); |
} |
out1str(" \b"); |
while (j-- > cursor) |
out1c('\b'); |
flushout(&output); |
} |
void input_end(int *cursor, int len) |
{ |
while (*cursor < len) { |
out1str("\033[C"); |
++*cursor; |
} |
flushout(&output); |
} |
void |
input_backspace(int *cursor, int *len) |
{ |
int j = 0; |
if (*cursor > 0) { |
out1str("\b \b"); |
--*cursor; |
memmove(parsenextc + *cursor, parsenextc + *cursor + 1, |
BUFSIZ - *cursor + 1); |
for (j = *cursor; j < (BUFSIZ - 1); j++) { |
if (!*(parsenextc + j)) |
break; |
else |
out1c(*(parsenextc + j)); |
} |
out1str(" \b"); |
while (j-- > *cursor) |
out1c('\b'); |
--*len; |
flushout(&output); |
} |
} |
int hetio_read_input(int fd) |
{ |
int nr = 0; |
if (!hetio_inter) { /* Are we an interactive shell? */ |
return -255; |
} else { |
int len = 0; |
int j = 0; |
int cursor = 0; |
int break_out = 0; |
int ret = 0; |
char c = 0; |
struct history *hp = his_end; |
if (!reset_term) { |
setIO(&new_term, &old_term); |
reset_term = 1; |
} else { |
tcsetattr(0, TCSANOW, &new_term); |
} |
memset(parsenextc, 0, BUFSIZ); |
while (1) { |
if ((ret = read(fd, &c, 1)) < 1) |
return ret; |
switch (c) { |
case 1: /* Control-A Beginning of line */ |
input_home(&cursor); |
break; |
case 5: /* Control-E EOL */ |
input_end(&cursor, len); |
break; |
case 4: /* Control-D */ |
#ifndef CTRL_D_DELETE |
return 0; |
#else |
if (cursor != len) { |
input_delete(cursor); |
len--; |
} |
break; |
#endif |
case '\b': /* Backspace */ |
case DEL: |
input_backspace(&cursor, &len); |
break; |
case '\n': /* Enter */ |
*(parsenextc + len++ + 1) = c; |
out1c(c); |
flushout(&output); |
break_out = 1; |
break; |
case ESC: /* escape sequence follows */ |
if ((ret = read(fd, &c, 1)) < 1) |
return ret; |
if (c == '[' || c == 'O' ) { /* 91 */ |
if ((ret = read(fd, &c, 1)) < 1) |
return ret; |
switch (c) { |
case 'A': |
if (hp && hp->p) { /* Up */ |
hp = hp->p; |
goto hop; |
} |
break; |
case 'B': |
if (hp && hp->n && hp->n->s) { /* Down */ |
hp = hp->n; |
goto hop; |
} |
break; |
hop: /* hop */ |
len = strlen(parsenextc); |
for (; cursor > 0; cursor--) /* return to begining of line */ |
out1c('\b'); |
for (j = 0; j < len; j++) /* erase old command */ |
out1c(' '); |
for (j = len; j > 0; j--) /* return to begining of line */ |
out1c('\b'); |
strcpy (parsenextc, hp->s); /* write new command */ |
len = strlen (hp->s); |
out1str(parsenextc); |
flushout(&output); |
cursor = len; |
break; |
case 'C': /* Right */ |
if (cursor < len) { |
out1str("\033[C"); |
cursor++; |
flushout(&output); |
} |
break; |
case 'D': /* Left */ |
if (cursor > 0) { |
out1str("\033[D"); |
cursor--; |
flushout(&output); |
} |
break; |
case '3': /* Delete */ |
if (cursor != len) { |
input_delete(cursor); |
len--; |
} |
break; |
case 'H': /* Home (xterm) */ |
case '1': /* Home (Ctrl-A) */ |
input_home(&cursor); |
break; |
case 'F': /* End (xterm_ */ |
case '4': /* End (Ctrl-E) */ |
input_end(&cursor, len); |
break; |
} |
if (c == '1' || c == '3' || c == '4') |
if ((ret = read(fd, &c, 1)) < 1) |
return ret; /* read 126 (~) */ |
} |
c = 0; |
break; |
default: /* If it's regular input, do the normal thing */ |
if (!isprint(c)) /* Skip non-printable characters */ |
break; |
if (len >= (BUFSIZ - 2)) /* Need to leave space for enter */ |
break; |
len++; |
if (cursor == (len - 1)) { /* Append if at the end of the line */ |
*(parsenextc + cursor) = c; |
} else { /* Insert otherwise */ |
memmove(parsenextc + cursor + 1, parsenextc + cursor, |
len - cursor - 1); |
*(parsenextc + cursor) = c; |
for (j = cursor; j < len; j++) |
out1c(*(parsenextc + j)); |
for (; j > cursor; j--) |
out1str("\033[D"); |
} |
cursor++; |
out1c(c); |
flushout(&output); |
break; |
} |
if (break_out) /* Enter is the command terminator, no more input. */ |
break; |
} |
nr = len + 1; |
tcsetattr(0, TCSANOW, &old_term); |
if (*(parsenextc)) { /* Handle command history log */ |
struct history *h = his_end; |
if (!h) { /* No previous history */ |
h = his_front = malloc(sizeof (struct history)); |
h->n = malloc(sizeof (struct history)); |
h->p = NULL; |
h->s = strdup(parsenextc); |
h->n->p = h; |
h->n->n = NULL; |
h->n->s = NULL; |
his_end = h->n; |
history_counter++; |
} else { /* Add a new history command */ |
h->n = malloc(sizeof (struct history)); |
h->n->p = h; |
h->n->n = NULL; |
h->n->s = NULL; |
h->s = strdup(parsenextc); |
his_end = h->n; |
if (history_counter >= MAX_HISTORY) { /* After max history, remove the last known command */ |
struct history *p = his_front->n; |
p->p = NULL; |
free(his_front->s); |
free(his_front); |
his_front = p; |
} else { |
history_counter++; |
} |
} |
} |
} |
return nr; |
} |
#endif |
/branches/dd/uspace/app/ash/mktokens |
---|
0,0 → 1,96 |
#!/bin/sh - |
# $NetBSD: mktokens,v 1.9 1999/07/09 03:05:50 christos Exp $ |
# |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)mktokens 8.1 (Berkeley) 5/31/93 |
# The following is a list of tokens. The second column is nonzero if the |
# token marks the end of a list. The third column is the name to print in |
# error messages. |
cat > /tmp/ka$$ <<\! |
TEOF 1 end of file |
TNL 0 newline |
TSEMI 0 ";" |
TBACKGND 0 "&" |
TAND 0 "&&" |
TOR 0 "||" |
TPIPE 0 "|" |
TLP 0 "(" |
TRP 1 ")" |
TENDCASE 1 ";;" |
TENDBQUOTE 1 "`" |
TREDIR 0 redirection |
TWORD 0 word |
TIF 0 "if" |
TTHEN 1 "then" |
TELSE 1 "else" |
TELIF 1 "elif" |
TFI 1 "fi" |
TWHILE 0 "while" |
TUNTIL 0 "until" |
TFOR 0 "for" |
TDO 1 "do" |
TDONE 1 "done" |
TBEGIN 0 "{" |
TEND 1 "}" |
TCASE 0 "case" |
TESAC 1 "esac" |
TNOT 0 "!" |
! |
nl=`wc -l /tmp/ka$$` |
exec > token.h |
awk '{print "#define " $1 " " NR-1}' /tmp/ka$$ |
echo ' |
/* Array indicating which tokens mark the end of a list */ |
const char tokendlist[] = {' |
awk '{print "\t" $2 ","}' /tmp/ka$$ |
echo '}; |
const char *const tokname[] = {' |
sed -e 's/"/\\"/g' \ |
-e 's/[^ ]*[ ][ ]*[^ ]*[ ][ ]*\(.*\)/ "\1",/' \ |
/tmp/ka$$ |
echo '}; |
' |
sed 's/"//g' /tmp/ka$$ | awk ' |
/TIF/{print "#define KWDOFFSET " NR-1; print ""; |
print "const char *const parsekwd[] = {"} |
/TIF/,/neverfound/{print " \"" $3 "\","}' |
echo ' 0 |
};' |
rm /tmp/ka$$ |
/branches/dd/uspace/app/ash/shell.h |
---|
0,0 → 1,86 |
/* $NetBSD: shell.h,v 1.13 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)shell.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* |
* The follow should be set to reflect the type of system you have: |
* JOBS -> 1 if you have Berkeley job control, 0 otherwise. |
* SHORTNAMES -> 1 if your linker cannot handle long names. |
* define BSD if you are running 4.2 BSD or later. |
* define SYSV if you are running under System V. |
* define DEBUG=1 to compile in debugging (set global "debug" to turn on) |
* define DEBUG=2 to compile in and turn on debugging. |
* |
* When debugging is on, debugging info will be written to $HOME/trace and |
* a quit signal will generate a core dump. |
*/ |
#define JOBS 0 |
#ifndef BSD |
#define BSD 1 |
#endif |
//#include "fake.h" |
#ifdef __STDC__ |
typedef void *pointer; |
#ifndef NULL |
#define NULL (void *)0 |
#endif |
#else /* not __STDC__ */ |
typedef char *pointer; |
#ifndef NULL |
#define NULL 0 |
#endif |
#endif /* not __STDC__ */ |
#define STATIC /* empty */ |
#define MKINIT /* empty */ |
#include <sys/cdefs.h> |
extern char nullstr[1]; /* null string */ |
#ifdef DEBUG |
#define TRACE(param) trace param |
#else |
#define TRACE(param) |
#endif |
/branches/dd/uspace/app/ash/hetio.h |
---|
0,0 → 1,22 |
/* |
* Termios command line History and Editting for NetBSD sh (ash) |
* Copyright (c) 1999 |
* Main code: Adam Rogoyski <rogoyski@cs.utexas.edu> |
* Etc: Dave Cinege <dcinege@psychosis.com> |
* |
* You may use this code as you wish, so long as the original author(s) |
* are attributed in any redistributions of the source code. |
* This code is 'as is' with no warranty. |
* This code may safely be consumed by a BSD or GPL license. |
* |
* v 0.5 19990328 Initial release |
* |
* Future plans: Simple file and path name completion. (like BASH) |
* |
*/ |
void hetio_init(void); |
int hetio_read_input(int fd); |
void hetio_reset_term(void); |
extern int hetio_inter; |
/branches/dd/uspace/app/ash/exec.c |
---|
0,0 → 1,1181 |
/* $NetBSD: exec.c,v 1.31 2000/11/01 19:21:41 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)exec.c 8.4 (Berkeley) 6/8/95"; |
#else |
__RCSID("$NetBSD: exec.c,v 1.31 2000/11/01 19:21:41 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include <errno.h> |
#include <stdlib.h> |
#include <sysexits.h> |
/* |
* When commands are first encountered, they are entered in a hash table. |
* This ensures that a full path search will not have to be done for them |
* on each invocation. |
* |
* We should investigate converting to a linear search, even though that |
* would make the command name "hash" a misnomer. |
*/ |
#include "shell.h" |
#include "main.h" |
#include "nodes.h" |
#include "parser.h" |
#include "redir.h" |
#include "eval.h" |
#include "exec.h" |
#include "builtins.h" |
#include "var.h" |
#include "options.h" |
#include "input.h" |
#include "output.h" |
#include "syntax.h" |
#include "memalloc.h" |
#include "error.h" |
#include "init.h" |
#include "mystring.h" |
#include "show.h" |
#include "jobs.h" |
#include "alias.h" |
#define CMDTABLESIZE 31 /* should be prime */ |
#define ARB 1 /* actual size determined at run time */ |
struct tblentry { |
struct tblentry *next; /* next entry in hash chain */ |
union param param; /* definition of builtin function */ |
short cmdtype; /* index identifying command */ |
char rehash; /* if set, cd done since entry created */ |
char cmdname[ARB]; /* name of command */ |
}; |
STATIC struct tblentry *cmdtable[CMDTABLESIZE]; |
STATIC int builtinloc = -1; /* index in path of %builtin, or -1 */ |
int exerrno = 0; /* Last exec error */ |
STATIC void tryexec (char *, char **, char **); |
STATIC void execinterp (char **, char **); |
STATIC void printentry (struct tblentry *, int); |
STATIC void clearcmdentry (int); |
STATIC struct tblentry *cmdlookup (char *, int); |
STATIC void delete_cmd_entry (void); |
STATIC int describe_command (char *, int); |
STATIC int path_change (const char *, int *); |
STATIC int is_regular_builtin (const char *); |
/* |
* Exec a program. Never returns. If you change this routine, you may |
* have to change the find_command routine as well. |
*/ |
void |
shellexec(argv, envp, path, idx) |
char **argv, **envp; |
const char *path; |
int idx; |
{ |
char *cmdname; |
int e; |
if (fd2 >= 0 && fd2 != 2) { |
close(fd2); |
} |
if (strchr(argv[0], '/') != NULL) { |
tryexec(argv[0], argv, envp); |
e = errno; |
} else { |
e = ENOENT; |
while ((cmdname = padvance(&path, argv[0])) != NULL) { |
if (--idx < 0 && pathopt == NULL) { |
tryexec(cmdname, argv, envp); |
if (errno != ENOENT && errno != ENOTDIR) |
e = errno; |
} |
stunalloc(cmdname); |
} |
} |
/* Map to POSIX errors */ |
switch (e) { |
case EACCES: |
exerrno = 126; |
break; |
case ENOENT: |
exerrno = 127; |
break; |
default: |
exerrno = 2; |
break; |
} |
exerror(EXEXEC, "%s: %s", argv[0], errmsg(e, E_EXEC)); |
/* NOTREACHED */ |
} |
STATIC void |
tryexec(cmd, argv, envp) |
char *cmd; |
char **argv; |
char **envp; |
{ |
int e; |
#if !defined(BSD) && !defined(linux) |
char *p; |
#endif |
#ifdef SYSV |
do { |
execve(cmd, argv, envp); |
} while (errno == EINTR); |
#else |
execve(cmd, argv, envp); |
#endif |
e = errno; |
if (e == ENOEXEC) { |
initshellproc(); |
setinputfile(cmd, 0); |
commandname = arg0 = savestr(argv[0]); |
#if !defined(BSD) && !defined(linux) |
pgetc(); pungetc(); /* fill up input buffer */ |
p = parsenextc; |
if (parsenleft > 2 && p[0] == '#' && p[1] == '!') { |
argv[0] = cmd; |
execinterp(argv, envp); |
} |
#endif |
setparam(argv + 1); |
exraise(EXSHELLPROC); |
} |
errno = e; |
} |
#if !defined(BSD) && !defined(linux) |
/* |
* Execute an interpreter introduced by "#!", for systems where this |
* feature has not been built into the kernel. If the interpreter is |
* the shell, return (effectively ignoring the "#!"). If the execution |
* of the interpreter fails, exit. |
* |
* This code peeks inside the input buffer in order to avoid actually |
* reading any input. It would benefit from a rewrite. |
*/ |
#define NEWARGS 5 |
STATIC void |
execinterp(argv, envp) |
char **argv, **envp; |
{ |
int n; |
char *inp; |
char *outp; |
char c; |
char *p; |
char **ap; |
char *newargs[NEWARGS]; |
int i; |
char **ap2; |
char **new; |
n = parsenleft - 2; |
inp = parsenextc + 2; |
ap = newargs; |
for (;;) { |
while (--n >= 0 && (*inp == ' ' || *inp == '\t')) |
inp++; |
if (n < 0) |
goto bad; |
if ((c = *inp++) == '\n') |
break; |
if (ap == &newargs[NEWARGS]) |
bad: error("Bad #! line"); |
STARTSTACKSTR(outp); |
do { |
STPUTC(c, outp); |
} while (--n >= 0 && (c = *inp++) != ' ' && c != '\t' && c != '\n'); |
STPUTC('\0', outp); |
n++, inp--; |
*ap++ = grabstackstr(outp); |
} |
if (ap == newargs + 1) { /* if no args, maybe no exec is needed */ |
p = newargs[0]; |
for (;;) { |
if (equal(p, "sh") || equal(p, "ash")) { |
return; |
} |
while (*p != '/') { |
if (*p == '\0') |
goto break2; |
p++; |
} |
p++; |
} |
break2:; |
} |
i = (char *)ap - (char *)newargs; /* size in bytes */ |
if (i == 0) |
error("Bad #! line"); |
for (ap2 = argv ; *ap2++ != NULL ; ); |
new = ckmalloc(i + ((char *)ap2 - (char *)argv)); |
ap = newargs, ap2 = new; |
while ((i -= sizeof (char **)) >= 0) |
*ap2++ = *ap++; |
ap = argv; |
while (*ap2++ = *ap++); |
shellexec(new, envp, pathval(), 0); |
/* NOTREACHED */ |
} |
#endif |
/* |
* Do a path search. The variable path (passed by reference) should be |
* set to the start of the path before the first call; padvance will update |
* this value as it proceeds. Successive calls to padvance will return |
* the possible path expansions in sequence. If an option (indicated by |
* a percent sign) appears in the path entry then the global variable |
* pathopt will be set to point to it; otherwise pathopt will be set to |
* NULL. |
*/ |
const char *pathopt; |
char * |
padvance(path, name) |
const char **path; |
const char *name; |
{ |
const char *p; |
char *q; |
const char *start; |
int len; |
if (*path == NULL) |
return NULL; |
start = *path; |
for (p = start ; *p && *p != ':' && *p != '%' ; p++); |
len = p - start + strlen(name) + 2; /* "2" is for '/' and '\0' */ |
while (stackblocksize() < len) |
growstackblock(); |
q = stackblock(); |
if (p != start) { |
memcpy(q, start, p - start); |
q += p - start; |
*q++ = '/'; |
} |
strcpy(q, name); |
pathopt = NULL; |
if (*p == '%') { |
pathopt = ++p; |
while (*p && *p != ':') p++; |
} |
if (*p == ':') |
*path = p + 1; |
else |
*path = NULL; |
return stalloc(len); |
} |
/*** Command hashing code ***/ |
int |
hashcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct tblentry **pp; |
struct tblentry *cmdp; |
int c; |
int verbose; |
struct cmdentry entry; |
char *name; |
verbose = 0; |
while ((c = nextopt("rv")) != '\0') { |
if (c == 'r') { |
clearcmdentry(0); |
} else if (c == 'v') { |
verbose++; |
} |
} |
if (*argptr == NULL) { |
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { |
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { |
if (cmdp->cmdtype != CMDBUILTIN) { |
printentry(cmdp, verbose); |
} |
} |
} |
return 0; |
} |
c = 0; |
while ((name = *argptr) != NULL) { |
if ((cmdp = cmdlookup(name, 0)) != NULL |
&& (cmdp->cmdtype == CMDNORMAL |
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0))) |
delete_cmd_entry(); |
find_command(name, &entry, DO_ERR, pathval()); |
if (entry.cmdtype == CMDUNKNOWN) c = 1; |
else if (verbose) { |
cmdp = cmdlookup(name, 0); |
if (cmdp) printentry(cmdp, verbose); |
flushall(); |
} |
argptr++; |
} |
return c; |
} |
STATIC void |
printentry(cmdp, verbose) |
struct tblentry *cmdp; |
int verbose; |
{ |
int idx; |
const char *path; |
char *name; |
if (cmdp->cmdtype == CMDNORMAL) { |
idx = cmdp->param.index; |
path = pathval(); |
do { |
name = padvance(&path, cmdp->cmdname); |
stunalloc(name); |
} while (--idx >= 0); |
out1str(name); |
} else if (cmdp->cmdtype == CMDBUILTIN) { |
out1fmt("builtin %s", cmdp->cmdname); |
} else if (cmdp->cmdtype == CMDFUNCTION) { |
out1fmt("function %s", cmdp->cmdname); |
if (verbose) { |
INTOFF; |
name = commandtext(cmdp->param.func); |
out1c(' '); |
out1str(name); |
ckfree(name); |
INTON; |
} |
#ifdef DEBUG |
} else { |
error("internal error: cmdtype %d", cmdp->cmdtype); |
#endif |
} |
if (cmdp->rehash) |
out1c('*'); |
out1c('\n'); |
} |
/* |
* Resolve a command name. If you change this routine, you may have to |
* change the shellexec routine as well. |
*/ |
void |
find_command(name, entry, act, path) |
char *name; |
struct cmdentry *entry; |
int act; |
const char *path; |
{ |
struct tblentry *cmdp; |
int idx; |
int prev; |
char *fullname; |
struct stat statb; |
int e; |
int i; |
int bltin; |
int firstchange; |
int updatetbl; |
int regular; |
/* If name contains a slash, don't use the hash table */ |
if (strchr(name, '/') != NULL) { |
if (act & DO_ABS) { |
while (stat(name, &statb) < 0) { |
#ifdef SYSV |
if (errno == EINTR) |
continue; |
#endif |
if (errno != ENOENT && errno != ENOTDIR) |
e = errno; |
entry->cmdtype = CMDUNKNOWN; |
entry->u.index = -1; |
return; |
} |
entry->cmdtype = CMDNORMAL; |
entry->u.index = -1; |
return; |
} |
entry->cmdtype = CMDNORMAL; |
entry->u.index = 0; |
return; |
} |
updatetbl = 1; |
if (act & DO_BRUTE) { |
firstchange = path_change(path, &bltin); |
} else { |
bltin = builtinloc; |
firstchange = 9999; |
} |
/* If name is in the table, and not invalidated by cd, we're done */ |
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->rehash == 0) { |
if (cmdp->cmdtype == CMDFUNCTION) { |
if (act & DO_NOFUN) { |
updatetbl = 0; |
} else { |
goto success; |
} |
} else if (act & DO_BRUTE) { |
if ((cmdp->cmdtype == CMDNORMAL && |
cmdp->param.index >= firstchange) || |
(cmdp->cmdtype == CMDBUILTIN && |
((builtinloc < 0 && bltin >= 0) ? |
bltin : builtinloc) >= firstchange)) { |
/* need to recompute the entry */ |
} else { |
goto success; |
} |
} else { |
goto success; |
} |
} |
if ((regular = is_regular_builtin(name))) { |
if (cmdp && (cmdp->cmdtype == CMDBUILTIN)) { |
goto success; |
} |
} else if (act & DO_BRUTE) { |
if (firstchange == 0) { |
updatetbl = 0; |
} |
} |
/* If %builtin not in path, check for builtin next */ |
if ((bltin < 0 || regular) && (i = find_builtin(name)) >= 0) { |
if (!updatetbl) { |
entry->cmdtype = CMDBUILTIN; |
entry->u.index = i; |
return; |
} |
INTOFF; |
cmdp = cmdlookup(name, 1); |
cmdp->cmdtype = CMDBUILTIN; |
cmdp->param.index = i; |
INTON; |
goto success; |
} |
/* We have to search path. */ |
prev = -1; /* where to start */ |
if (cmdp && cmdp->rehash) { /* doing a rehash */ |
if (cmdp->cmdtype == CMDBUILTIN) |
prev = builtinloc; |
else |
prev = cmdp->param.index; |
} |
e = ENOENT; |
idx = -1; |
loop: |
while ((fullname = padvance(&path, name)) != NULL) { |
stunalloc(fullname); |
idx++; |
if (idx >= firstchange) { |
updatetbl = 0; |
} |
if (pathopt) { |
if (prefix("builtin", pathopt)) { |
if ((i = find_builtin(name)) >= 0) { |
if (!updatetbl) { |
entry->cmdtype = CMDBUILTIN; |
entry->u.index = i; |
return; |
} |
INTOFF; |
cmdp = cmdlookup(name, 1); |
cmdp->cmdtype = CMDBUILTIN; |
cmdp->param.index = i; |
INTON; |
goto success; |
} else { |
continue; |
} |
} else if (!(act & DO_NOFUN) && |
prefix("func", pathopt)) { |
/* handled below */ |
} else { |
continue; /* ignore unimplemented options */ |
} |
} |
/* if rehash, don't redo absolute path names */ |
if (fullname[0] == '/' && idx <= prev && |
idx < firstchange) { |
if (idx < prev) |
continue; |
TRACE(("searchexec \"%s\": no change\n", name)); |
goto success; |
} |
while (stat(fullname, &statb) < 0) { |
#ifdef SYSV |
if (errno == EINTR) |
continue; |
#endif |
if (errno != ENOENT && errno != ENOTDIR) |
e = errno; |
goto loop; |
} |
e = EACCES; /* if we fail, this will be the error */ |
if (!S_ISREG(statb.st_mode)) |
continue; |
if (pathopt) { /* this is a %func directory */ |
stalloc(strlen(fullname) + 1); |
readcmdfile(fullname); |
if ((cmdp = cmdlookup(name, 0)) == NULL || cmdp->cmdtype != CMDFUNCTION) |
error("%s not defined in %s", name, fullname); |
stunalloc(fullname); |
goto success; |
} |
#ifdef notdef |
if (statb.st_uid == geteuid()) { |
if ((statb.st_mode & 0100) == 0) |
goto loop; |
} else if (statb.st_gid == getegid()) { |
if ((statb.st_mode & 010) == 0) |
goto loop; |
} else { |
if ((statb.st_mode & 01) == 0) |
goto loop; |
} |
#endif |
TRACE(("searchexec \"%s\" returns \"%s\"\n", name, fullname)); |
/* If we aren't called with DO_BRUTE and cmdp is set, it must |
be a function and we're being called with DO_NOFUN */ |
if (!updatetbl) { |
entry->cmdtype = CMDNORMAL; |
entry->u.index = idx; |
return; |
} |
INTOFF; |
cmdp = cmdlookup(name, 1); |
cmdp->cmdtype = CMDNORMAL; |
cmdp->param.index = idx; |
INTON; |
goto success; |
} |
/* We failed. If there was an entry for this command, delete it */ |
if (cmdp && updatetbl) |
delete_cmd_entry(); |
if (act & DO_ERR) |
outfmt(out2, "%s: %s\n", name, errmsg(e, E_EXEC)); |
entry->cmdtype = CMDUNKNOWN; |
return; |
success: |
cmdp->rehash = 0; |
entry->cmdtype = cmdp->cmdtype; |
entry->u = cmdp->param; |
} |
/* |
* Search the table of builtin commands. |
*/ |
int |
find_builtin(name) |
char *name; |
{ |
const struct builtincmd *bp; |
for (bp = builtincmd ; bp->name ; bp++) { |
if (*bp->name == *name && equal(bp->name, name)) |
return bp->code; |
} |
return -1; |
} |
/* |
* Called when a cd is done. Marks all commands so the next time they |
* are executed they will be rehashed. |
*/ |
void |
hashcd() { |
struct tblentry **pp; |
struct tblentry *cmdp; |
for (pp = cmdtable ; pp < &cmdtable[CMDTABLESIZE] ; pp++) { |
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { |
if (cmdp->cmdtype == CMDNORMAL |
|| (cmdp->cmdtype == CMDBUILTIN && builtinloc >= 0)) |
cmdp->rehash = 1; |
} |
} |
} |
/* |
* Called before PATH is changed. The argument is the new value of PATH; |
* pathval() still returns the old value at this point. Called with |
* interrupts off. |
*/ |
void |
changepath(newval) |
const char *newval; |
{ |
int firstchange; |
int bltin; |
firstchange = path_change(newval, &bltin); |
if (builtinloc < 0 && bltin >= 0) |
builtinloc = bltin; /* zap builtins */ |
clearcmdentry(firstchange); |
builtinloc = bltin; |
} |
/* |
* Clear out command entries. The argument specifies the first entry in |
* PATH which has changed. |
*/ |
STATIC void |
clearcmdentry(firstchange) |
int firstchange; |
{ |
struct tblentry **tblp; |
struct tblentry **pp; |
struct tblentry *cmdp; |
INTOFF; |
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { |
pp = tblp; |
while ((cmdp = *pp) != NULL) { |
if ((cmdp->cmdtype == CMDNORMAL && |
cmdp->param.index >= firstchange) |
|| (cmdp->cmdtype == CMDBUILTIN && |
builtinloc >= firstchange)) { |
*pp = cmdp->next; |
ckfree(cmdp); |
} else { |
pp = &cmdp->next; |
} |
} |
} |
INTON; |
} |
/* |
* Delete all functions. |
*/ |
#ifdef mkinit |
MKINIT void deletefuncs (void); |
SHELLPROC { |
deletefuncs(); |
} |
#endif |
void |
deletefuncs() { |
struct tblentry **tblp; |
struct tblentry **pp; |
struct tblentry *cmdp; |
INTOFF; |
for (tblp = cmdtable ; tblp < &cmdtable[CMDTABLESIZE] ; tblp++) { |
pp = tblp; |
while ((cmdp = *pp) != NULL) { |
if (cmdp->cmdtype == CMDFUNCTION) { |
*pp = cmdp->next; |
freefunc(cmdp->param.func); |
ckfree(cmdp); |
} else { |
pp = &cmdp->next; |
} |
} |
} |
INTON; |
} |
/* |
* Locate a command in the command hash table. If "add" is nonzero, |
* add the command to the table if it is not already present. The |
* variable "lastcmdentry" is set to point to the address of the link |
* pointing to the entry, so that delete_cmd_entry can delete the |
* entry. |
*/ |
struct tblentry **lastcmdentry; |
STATIC struct tblentry * |
cmdlookup(name, add) |
char *name; |
int add; |
{ |
int hashval; |
char *p; |
struct tblentry *cmdp; |
struct tblentry **pp; |
p = name; |
hashval = *p << 4; |
while (*p) |
hashval += *p++; |
hashval &= 0x7FFF; |
pp = &cmdtable[hashval % CMDTABLESIZE]; |
for (cmdp = *pp ; cmdp ; cmdp = cmdp->next) { |
if (equal(cmdp->cmdname, name)) |
break; |
pp = &cmdp->next; |
} |
if (add && cmdp == NULL) { |
INTOFF; |
cmdp = *pp = ckmalloc(sizeof (struct tblentry) - ARB |
+ strlen(name) + 1); |
cmdp->next = NULL; |
cmdp->cmdtype = CMDUNKNOWN; |
cmdp->rehash = 0; |
strcpy(cmdp->cmdname, name); |
INTON; |
} |
lastcmdentry = pp; |
return cmdp; |
} |
/* |
* Delete the command entry returned on the last lookup. |
*/ |
STATIC void |
delete_cmd_entry() { |
struct tblentry *cmdp; |
INTOFF; |
cmdp = *lastcmdentry; |
*lastcmdentry = cmdp->next; |
ckfree(cmdp); |
INTON; |
} |
#ifdef notdef |
void |
getcmdentry(name, entry) |
char *name; |
struct cmdentry *entry; |
{ |
struct tblentry *cmdp = cmdlookup(name, 0); |
if (cmdp) { |
entry->u = cmdp->param; |
entry->cmdtype = cmdp->cmdtype; |
} else { |
entry->cmdtype = CMDUNKNOWN; |
entry->u.index = 0; |
} |
} |
#endif |
/* |
* Add a new command entry, replacing any existing command entry for |
* the same name. |
*/ |
void |
addcmdentry(name, entry) |
char *name; |
struct cmdentry *entry; |
{ |
struct tblentry *cmdp; |
INTOFF; |
cmdp = cmdlookup(name, 1); |
if (cmdp->cmdtype == CMDFUNCTION) { |
freefunc(cmdp->param.func); |
} |
cmdp->cmdtype = entry->cmdtype; |
cmdp->param = entry->u; |
INTON; |
} |
/* |
* Define a shell function. |
*/ |
void |
defun(name, func) |
char *name; |
union node *func; |
{ |
struct cmdentry entry; |
entry.cmdtype = CMDFUNCTION; |
entry.u.func = copyfunc(func); |
addcmdentry(name, &entry); |
} |
/* |
* Delete a function if it exists. |
*/ |
int |
unsetfunc(name) |
char *name; |
{ |
struct tblentry *cmdp; |
if ((cmdp = cmdlookup(name, 0)) != NULL && cmdp->cmdtype == CMDFUNCTION) { |
freefunc(cmdp->param.func); |
delete_cmd_entry(); |
return (0); |
} |
return (1); |
} |
/* |
* Locate and print what a word is... |
*/ |
int |
typecmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct cmdentry entry; |
struct tblentry *cmdp; |
char * const *pp; |
struct alias *ap; |
int i; |
int err = 0; |
extern char *const parsekwd[]; |
for (i = 1; i < argc; i++) { |
out1str(argv[i]); |
/* First look at the keywords */ |
for (pp = parsekwd; *pp; pp++) |
if (**pp == *argv[i] && equal(*pp, argv[i])) |
break; |
if (*pp) { |
out1str(" is a shell keyword\n"); |
continue; |
} |
/* Then look at the aliases */ |
if ((ap = lookupalias(argv[i], 1)) != NULL) { |
out1fmt(" is an alias for %s\n", ap->val); |
continue; |
} |
/* Then check if it is a tracked alias */ |
if ((cmdp = cmdlookup(argv[i], 0)) != NULL) { |
entry.cmdtype = cmdp->cmdtype; |
entry.u = cmdp->param; |
} |
else { |
/* Finally use brute force */ |
find_command(argv[i], &entry, DO_ABS, pathval()); |
} |
switch (entry.cmdtype) { |
case CMDNORMAL: { |
if (strchr(argv[i], '/') == NULL) { |
const char *path = pathval(); |
char *name; |
int j = entry.u.index; |
do { |
name = padvance(&path, argv[i]); |
stunalloc(name); |
} while (--j >= 0); |
out1fmt(" is%s %s\n", |
cmdp ? " a tracked alias for" : "", name); |
} else { |
if (access(argv[i], X_OK) == 0) |
out1fmt(" is %s\n", argv[i]); |
else |
out1fmt(": %s\n", strerror(errno)); |
} |
break; |
} |
case CMDFUNCTION: |
out1str(" is a shell function\n"); |
break; |
case CMDBUILTIN: |
out1str(" is a shell builtin\n"); |
break; |
default: |
out1str(": not found\n"); |
err |= 127; |
break; |
} |
} |
return err; |
} |
STATIC int |
describe_command(command, verbose) |
char *command; |
int verbose; |
{ |
struct cmdentry entry; |
struct tblentry *cmdp; |
char **pp; |
struct alias *ap; |
extern char *const parsekwd[]; |
for (pp = (char **)parsekwd; *pp; pp++) |
if (**pp == *command && equal(*pp, command)) |
break; |
if (*pp) { |
if (verbose) { |
out1fmt("%s is a reserved word\n", command); |
} else { |
out1fmt("%s\n", command); |
} |
return 0; |
} |
/* Then look at the aliases */ |
if ((ap = lookupalias(command, 1)) != NULL) { |
if (verbose) { |
out1fmt("%s is aliased to `%s'\n", command, ap->val); |
} else { |
out1fmt("alias %s='%s'\n", command, ap->val); |
} |
return 0; |
} |
/* Then check if it is a tracked alias */ |
if ((cmdp = cmdlookup(command, 0)) != NULL) { |
entry.cmdtype = cmdp->cmdtype; |
entry.u = cmdp->param; |
} |
else { |
/* Finally use brute force */ |
find_command(command, &entry, DO_ABS, pathval()); |
} |
switch (entry.cmdtype) { |
case CMDNORMAL: { |
int j = entry.u.index; |
const char *path = pathval(); |
char *name; |
if (j == -1) |
name = command; |
else { |
do { |
name = padvance(&path, command); |
stunalloc(name); |
} while (--j >= 0); |
} |
if (verbose) { |
out1fmt("%s is %s\n", command, name); |
} else { |
out1fmt("%s\n", name); |
} |
break; |
} |
case CMDFUNCTION: |
if (verbose) { |
out1fmt("%s is a function\n", command); |
} else { |
out1fmt("%s\n", command); |
} |
break; |
case CMDBUILTIN: |
if (verbose) { |
if (is_special_builtin(command)) { |
out1fmt("%s is a special built-in utility\n", command); |
} else { |
out1fmt("%s is a built-in utility\n", command); |
} |
} else { |
out1fmt("%s\n", command); |
} |
break; |
default: |
outfmt(out2, "%s not found\n", command); |
return 127; |
} |
return 0; |
} |
int |
commandcmd(argc, argv) |
int argc; |
char **argv; |
{ |
int c; |
int default_path = 0; |
int verify_only = 0; |
int verbose_verify_only = 0; |
while ((c = nextopt("pvV")) != '\0') |
switch (c) { |
case 'p': |
default_path = 1; |
break; |
case 'v': |
verify_only = 1; |
break; |
case 'V': |
verbose_verify_only = 1; |
break; |
default: |
outfmt(out2, |
"command: nextopt returned character code 0%o\n", c); |
return EX_SOFTWARE; |
} |
if (default_path + verify_only + verbose_verify_only > 1 || |
!*argptr) { |
outfmt(out2, |
"command [-p] command [arg ...]\n"); |
outfmt(out2, |
"command {-v|-V} command\n"); |
return EX_USAGE; |
} |
if (verify_only || verbose_verify_only) { |
return describe_command(*argptr, verbose_verify_only); |
} |
return 0; |
} |
STATIC int |
path_change(newval, bltin) |
const char *newval; |
int *bltin; |
{ |
const char *old, *new; |
int idx; |
int firstchange; |
old = pathval(); |
new = newval; |
firstchange = 9999; /* assume no change */ |
idx = 0; |
*bltin = -1; |
for (;;) { |
if (*old != *new) { |
firstchange = idx; |
if ((*old == '\0' && *new == ':') |
|| (*old == ':' && *new == '\0')) |
firstchange++; |
old = new; /* ignore subsequent differences */ |
} |
if (*new == '\0') |
break; |
if (*new == '%' && *bltin < 0 && prefix("builtin", new + 1)) |
*bltin = idx; |
if (*new == ':') { |
idx++; |
} |
new++, old++; |
} |
if (builtinloc >= 0 && *bltin < 0) |
firstchange = 0; |
return firstchange; |
} |
STATIC int |
is_regular_builtin(name) |
const char *name; |
{ |
static const char *regular_builtins[] = { |
"alias", "bg", "cd", "command", "false", "fc", "fg", |
"getopts", "jobs", "kill", "newgrp", "read", "true", |
"umask", "unalias", "wait", (char *)NULL |
}; |
int i; |
if (!name) return 0; |
for (i = 0; regular_builtins[i]; i++) |
if (equal(name, regular_builtins[i])) return 1; |
return 0; |
} |
/branches/dd/uspace/app/ash/cd.c |
---|
0,0 → 1,382 |
/* $NetBSD: cd.c,v 1.27 1999/07/09 03:05:49 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)cd.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: cd.c,v 1.27 1999/07/09 03:05:49 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <errno.h> |
/* |
* The cd and pwd commands. |
*/ |
#include "shell.h" |
#include "var.h" |
#include "nodes.h" /* for jobs.h */ |
#include "jobs.h" |
#include "options.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "exec.h" |
#include "redir.h" |
#include "mystring.h" |
#include "show.h" |
#include "cd.h" |
STATIC int docd (char *, int); |
STATIC char *getcomponent (void); |
STATIC void updatepwd (char *); |
char *curdir = NULL; /* current working directory */ |
char *prevdir; /* previous working directory */ |
STATIC char *cdcomppath; |
int |
cdcmd(argc, argv) |
int argc; |
char **argv; |
{ |
const char *dest; |
const char *path; |
char *p; |
struct stat statb; |
int print = 0; |
nextopt(nullstr); |
if ((dest = *argptr) == NULL && (dest = bltinlookup("HOME", 1)) == NULL) |
error("HOME not set"); |
if (*dest == '\0') |
dest = "."; |
if (dest[0] == '-' && dest[1] == '\0') { |
dest = prevdir ? prevdir : curdir; |
print = 1; |
if (dest) |
print = 1; |
else |
dest = "."; |
} |
if (*dest == '/' || (path = bltinlookup("CDPATH", 1)) == NULL) |
path = nullstr; |
while ((p = padvance(&path, dest)) != NULL) { |
if (stat(p, &statb) >= 0 && S_ISDIR(statb.st_mode)) { |
if (!print) { |
/* |
* XXX - rethink |
*/ |
if (p[0] == '.' && p[1] == '/' && p[2] != '\0') |
p += 2; |
print = strcmp(p, dest); |
} |
if (docd(p, print) >= 0) |
return 0; |
} |
} |
error("can't cd to %s", dest); |
/* NOTREACHED */ |
} |
/* |
* Actually do the chdir. In an interactive shell, print the |
* directory name if "print" is nonzero. |
*/ |
STATIC int |
docd(dest, print) |
char *dest; |
int print; |
{ |
char *p; |
char *q; |
char *component; |
struct stat statb; |
int first; |
int badstat; |
TRACE(("docd(\"%s\", %d) called\n", dest, print)); |
/* |
* Check each component of the path. If we find a symlink or |
* something we can't stat, clear curdir to force a getcwd() |
* next time we get the value of the current directory. |
*/ |
badstat = 0; |
cdcomppath = stalloc(strlen(dest) + 1); |
scopy(dest, cdcomppath); |
STARTSTACKSTR(p); |
if (*dest == '/') { |
STPUTC('/', p); |
cdcomppath++; |
} |
first = 1; |
while ((q = getcomponent()) != NULL) { |
if (q[0] == '\0' || (q[0] == '.' && q[1] == '\0')) |
continue; |
if (! first) |
STPUTC('/', p); |
first = 0; |
component = q; |
while (*q) |
STPUTC(*q++, p); |
if (equal(component, "..")) |
continue; |
STACKSTRNUL(p); |
if ((lstat(stackblock(), &statb) < 0) |
|| (S_ISLNK(statb.st_mode))) { |
/* print = 1; */ |
badstat = 1; |
break; |
} |
} |
INTOFF; |
if (chdir(dest) < 0) { |
INTON; |
return -1; |
} |
updatepwd(badstat ? NULL : dest); |
INTON; |
if (print && iflag && curdir) |
out1fmt("%s\n", curdir); |
return 0; |
} |
/* |
* Get the next component of the path name pointed to by cdcomppath. |
* This routine overwrites the string pointed to by cdcomppath. |
*/ |
STATIC char * |
getcomponent() { |
char *p; |
char *start; |
if ((p = cdcomppath) == NULL) |
return NULL; |
start = cdcomppath; |
while (*p != '/' && *p != '\0') |
p++; |
if (*p == '\0') { |
cdcomppath = NULL; |
} else { |
*p++ = '\0'; |
cdcomppath = p; |
} |
return start; |
} |
/* |
* Update curdir (the name of the current directory) in response to a |
* cd command. We also call hashcd to let the routines in exec.c know |
* that the current directory has changed. |
*/ |
STATIC void |
updatepwd(dir) |
char *dir; |
{ |
char *new; |
char *p; |
hashcd(); /* update command hash table */ |
/* |
* If our argument is NULL, we don't know the current directory |
* any more because we traversed a symbolic link or something |
* we couldn't stat(). |
*/ |
if (dir == NULL || curdir == NULL) { |
if (prevdir) |
ckfree(prevdir); |
INTOFF; |
prevdir = curdir; |
curdir = NULL; |
getpwd(); |
setvar("PWD", curdir, VEXPORT|VTEXTFIXED); |
setvar("OLDPWD", prevdir, VEXPORT|VTEXTFIXED); |
INTON; |
return; |
} |
cdcomppath = stalloc(strlen(dir) + 1); |
scopy(dir, cdcomppath); |
STARTSTACKSTR(new); |
if (*dir != '/') { |
p = curdir; |
while (*p) |
STPUTC(*p++, new); |
if (p[-1] == '/') |
STUNPUTC(new); |
} |
while ((p = getcomponent()) != NULL) { |
if (equal(p, "..")) { |
while (new > stackblock() && (STUNPUTC(new), *new) != '/'); |
} else if (*p != '\0' && ! equal(p, ".")) { |
STPUTC('/', new); |
while (*p) |
STPUTC(*p++, new); |
} |
} |
if (new == stackblock()) |
STPUTC('/', new); |
STACKSTRNUL(new); |
INTOFF; |
if (prevdir) |
ckfree(prevdir); |
prevdir = curdir; |
curdir = savestr(stackblock()); |
setvar("PWD", curdir, VEXPORT|VTEXTFIXED); |
setvar("OLDPWD", prevdir, VEXPORT|VTEXTFIXED); |
INTON; |
} |
int |
pwdcmd(argc, argv) |
int argc; |
char **argv; |
{ |
getpwd(); |
out1str(curdir); |
out1c('\n'); |
return 0; |
} |
#define MAXPWD 256 |
/* |
* Find out what the current directory is. If we already know the current |
* directory, this routine returns immediately. |
*/ |
void |
getpwd() |
{ |
char buf[MAXPWD]; |
if (curdir) |
return; |
/* |
* Things are a bit complicated here; we could have just used |
* getcwd, but traditionally getcwd is implemented using popen |
* to /bin/pwd. This creates a problem for us, since we cannot |
* keep track of the job if it is being ran behind our backs. |
* So we re-implement getcwd(), and we suppress interrupts |
* throughout the process. This is not completely safe, since |
* the user can still break out of it by killing the pwd program. |
* We still try to use getcwd for systems that we know have a |
* c implementation of getcwd, that does not open a pipe to |
* /bin/pwd. |
*/ |
#if defined(__NetBSD__) || defined(__SVR4) || defined(__GLIBC__) |
if (getcwd(buf, sizeof(buf)) == NULL) { |
char *pwd = getenv("PWD"); |
struct stat stdot, stpwd; |
if (pwd && *pwd == '/' && stat(".", &stdot) != -1 && |
stat(pwd, &stpwd) != -1 && |
stdot.st_dev == stpwd.st_dev && |
stdot.st_ino == stpwd.st_ino) { |
curdir = savestr(pwd); |
return; |
} |
error("getcwd() failed: %s", strerror(errno)); |
} |
curdir = savestr(buf); |
#else |
{ |
char *p; |
int i; |
int status; |
struct job *jp; |
int pip[2]; |
INTOFF; |
if (pipe(pip) < 0) |
error("Pipe call failed"); |
jp = makejob((union node *)NULL, 1); |
if (forkshell(jp, (union node *)NULL, FORK_NOJOB) == 0) { |
(void) close(pip[0]); |
if (pip[1] != 1) { |
close(1); |
copyfd(pip[1], 1); |
close(pip[1]); |
} |
(void) execl("/bin/pwd", "pwd", (char *)0); |
error("Cannot exec /bin/pwd"); |
} |
(void) close(pip[1]); |
pip[1] = -1; |
p = buf; |
while ((i = read(pip[0], p, buf + MAXPWD - p)) > 0 |
|| (i == -1 && errno == EINTR)) { |
if (i > 0) |
p += i; |
} |
(void) close(pip[0]); |
pip[0] = -1; |
status = waitforjob(jp); |
if (status != 0) |
error((char *)0); |
if (i < 0 || p == buf || p[-1] != '\n') |
error("pwd command failed"); |
p[-1] = '\0'; |
} |
curdir = savestr(buf); |
INTON; |
#endif |
} |
/branches/dd/uspace/app/ash/bltin/echo.c |
---|
0,0 → 1,127 |
/* $NetBSD: echo.c,v 1.8 1996/11/02 18:26:06 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)echo.c 8.1 (Berkeley) 5/31/93 |
*/ |
/* |
* Echo command. |
*/ |
#define main echocmd |
#ifdef _GNU_SOURCE |
#include <stdio.h> |
#include "../mystring.h" |
#else |
#include "bltin.h" |
#endif |
/* #define eflag 1 */ |
int |
main(argc, argv) char **argv; { |
register char **ap; |
register char *p; |
register char c; |
int nflag = 0; |
#ifndef eflag |
int eflag = 0; |
#endif |
ap = argv; |
if (argc) |
ap++; |
while ((p = *ap) != NULL && *p == '-') { |
if (equal(p, "-n")) { |
nflag = 1; |
} else if (equal(p, "-e")) { |
#ifndef eflag |
eflag = 1; |
#endif |
} else if (equal(p, "-E")) { |
#ifndef eflag |
eflag = 0; |
#endif |
} |
else break; |
ap++; |
} |
while ((p = *ap++) != NULL) { |
while ((c = *p++) != '\0') { |
if (c == '\\' && eflag) { |
switch (c = *p++) { |
case 'a': c = '\007'; break; |
case 'b': c = '\b'; break; |
case 'c': return 0; /* exit */ |
case 'e': c = '\033'; break; |
case 'f': c = '\f'; break; |
case 'n': c = '\n'; break; |
case 'r': c = '\r'; break; |
case 't': c = '\t'; break; |
case 'v': c = '\v'; break; |
case '\\': break; /* c = '\\' */ |
case '0': case '1': case '2': case '3': |
case '4': case '5': case '6': case '7': |
c -= '0'; |
if (*p >= '0' && *p <= '7') |
c = c * 8 + (*p++ - '0'); |
if (*p >= '0' && *p <= '7') |
c = c * 8 + (*p++ - '0'); |
break; |
default: |
p--; |
break; |
} |
} |
putchar(c); |
} |
if (*ap) |
putchar(' '); |
} |
if (! nflag) |
putchar('\n'); |
#ifdef _GNU_SOURCE |
fflush(stdout); |
if (ferror(stdout)) { |
clearerr(stdout); |
return 1; |
} |
#endif |
return 0; |
} |
/branches/dd/uspace/app/ash/bltin/test.c |
---|
0,0 → 1,583 |
/* $NetBSD: test.c,v 1.22 2000/04/09 23:24:59 christos Exp $ */ |
/* |
* test(1); version 7-like -- author Erik Baalbergen |
* modified by Eric Gisin to be used as built-in. |
* modified by Arnold Robbins to add SVR3 compatibility |
* (-x -c -b -p -u -g -k) plus Korn's -L -nt -ot -ef and new -S (socket). |
* modified by J.T. Conklin for NetBSD. |
* |
* This program is in the Public Domain. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
__RCSID("$NetBSD: test.c,v 1.22 2000/04/09 23:24:59 christos Exp $"); |
#endif |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <ctype.h> |
#include <errno.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <string.h> |
#include <err.h> |
#ifdef __STDC__ |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
/* test(1) accepts the following grammar: |
oexpr ::= aexpr | aexpr "-o" oexpr ; |
aexpr ::= nexpr | nexpr "-a" aexpr ; |
nexpr ::= primary | "!" primary |
primary ::= unary-operator operand |
| operand binary-operator operand |
| operand |
| "(" oexpr ")" |
; |
unary-operator ::= "-r"|"-w"|"-x"|"-f"|"-d"|"-c"|"-b"|"-p"| |
"-u"|"-g"|"-k"|"-s"|"-t"|"-z"|"-n"|"-o"|"-O"|"-G"|"-L"|"-S"; |
binary-operator ::= "="|"!="|"-eq"|"-ne"|"-ge"|"-gt"|"-le"|"-lt"| |
"-nt"|"-ot"|"-ef"; |
operand ::= <any legal UNIX file name> |
*/ |
enum token { |
EOI, |
FILRD, |
FILWR, |
FILEX, |
FILEXIST, |
FILREG, |
FILDIR, |
FILCDEV, |
FILBDEV, |
FILFIFO, |
FILSOCK, |
FILSYM, |
FILGZ, |
FILTT, |
FILSUID, |
FILSGID, |
FILSTCK, |
FILNT, |
FILOT, |
FILEQ, |
FILUID, |
FILGID, |
STREZ, |
STRNZ, |
STREQ, |
STRNE, |
STRLT, |
STRGT, |
INTEQ, |
INTNE, |
INTGE, |
INTGT, |
INTLE, |
INTLT, |
UNOT, |
BAND, |
BOR, |
LPAREN, |
RPAREN, |
OPERAND |
}; |
enum token_types { |
UNOP, |
BINOP, |
BUNOP, |
BBINOP, |
PAREN |
}; |
static struct t_op { |
const char *op_text; |
short op_num, op_type; |
} const ops [] = { |
{"-r", FILRD, UNOP}, |
{"-w", FILWR, UNOP}, |
{"-x", FILEX, UNOP}, |
{"-e", FILEXIST,UNOP}, |
{"-f", FILREG, UNOP}, |
{"-d", FILDIR, UNOP}, |
{"-c", FILCDEV,UNOP}, |
{"-b", FILBDEV,UNOP}, |
{"-p", FILFIFO,UNOP}, |
{"-u", FILSUID,UNOP}, |
{"-g", FILSGID,UNOP}, |
{"-k", FILSTCK,UNOP}, |
{"-s", FILGZ, UNOP}, |
{"-t", FILTT, UNOP}, |
{"-z", STREZ, UNOP}, |
{"-n", STRNZ, UNOP}, |
{"-h", FILSYM, UNOP}, /* for backwards compat */ |
{"-O", FILUID, UNOP}, |
{"-G", FILGID, UNOP}, |
{"-L", FILSYM, UNOP}, |
{"-S", FILSOCK,UNOP}, |
{"=", STREQ, BINOP}, |
{"!=", STRNE, BINOP}, |
{"<", STRLT, BINOP}, |
{">", STRGT, BINOP}, |
{"-eq", INTEQ, BINOP}, |
{"-ne", INTNE, BINOP}, |
{"-ge", INTGE, BINOP}, |
{"-gt", INTGT, BINOP}, |
{"-le", INTLE, BINOP}, |
{"-lt", INTLT, BINOP}, |
{"-nt", FILNT, BINOP}, |
{"-ot", FILOT, BINOP}, |
{"-ef", FILEQ, BINOP}, |
{"!", UNOT, BUNOP}, |
{"-a", BAND, BBINOP}, |
{"-o", BOR, BBINOP}, |
{"(", LPAREN, PAREN}, |
{")", RPAREN, PAREN}, |
{0, 0, 0} |
}; |
static char **t_wp; |
static struct t_op const *t_wp_op; |
static gid_t *group_array = NULL; |
static int ngroups; |
static void syntax __P((const char *, const char *)); |
static int oexpr __P((enum token)); |
static int aexpr __P((enum token)); |
static int nexpr __P((enum token)); |
static int primary __P((enum token)); |
static int binop __P((void)); |
static int filstat __P((char *, enum token)); |
static enum token t_lex __P((char *)); |
static int isoperand __P((void)); |
static int getn __P((const char *)); |
static int newerf __P((const char *, const char *)); |
static int olderf __P((const char *, const char *)); |
static int equalf __P((const char *, const char *)); |
static int test_eaccess(); |
static int bash_group_member(); |
static void initialize_group_array(); |
#if defined(SHELL) |
extern void error __P((const char *, ...)) __attribute__((__noreturn__)); |
#else |
static void error __P((const char *, ...)) __attribute__((__noreturn__)); |
static void |
#ifdef __STDC__ |
error(const char *msg, ...) |
#else |
error(va_alist) |
va_dcl |
#endif |
{ |
va_list ap; |
#ifndef __STDC__ |
const char *msg; |
va_start(ap); |
msg = va_arg(ap, const char *); |
#else |
va_start(ap, msg); |
#endif |
verrx(2, msg, ap); |
/*NOTREACHED*/ |
va_end(ap); |
} |
#endif |
#ifdef SHELL |
int testcmd __P((int, char **)); |
int |
testcmd(argc, argv) |
int argc; |
char **argv; |
#else |
int main __P((int, char **)); |
int |
main(argc, argv) |
int argc; |
char **argv; |
#endif |
{ |
int res; |
if (strcmp(argv[0], "[") == 0) { |
if (strcmp(argv[--argc], "]")) |
error("missing ]"); |
argv[argc] = NULL; |
} |
if (argc < 2) |
return 1; |
t_wp = &argv[1]; |
res = !oexpr(t_lex(*t_wp)); |
if (*t_wp != NULL && *++t_wp != NULL) |
syntax(*t_wp, "unexpected operator"); |
return res; |
} |
static void |
syntax(op, msg) |
const char *op; |
const char *msg; |
{ |
if (op && *op) |
error("%s: %s", op, msg); |
else |
error("%s", msg); |
} |
static int |
oexpr(n) |
enum token n; |
{ |
int res; |
res = aexpr(n); |
if (t_lex(*++t_wp) == BOR) |
return oexpr(t_lex(*++t_wp)) || res; |
t_wp--; |
return res; |
} |
static int |
aexpr(n) |
enum token n; |
{ |
int res; |
res = nexpr(n); |
if (t_lex(*++t_wp) == BAND) |
return aexpr(t_lex(*++t_wp)) && res; |
t_wp--; |
return res; |
} |
static int |
nexpr(n) |
enum token n; /* token */ |
{ |
if (n == UNOT) |
return !nexpr(t_lex(*++t_wp)); |
return primary(n); |
} |
static int |
primary(n) |
enum token n; |
{ |
enum token nn; |
int res; |
if (n == EOI) |
return 0; /* missing expression */ |
if (n == LPAREN) { |
if ((nn = t_lex(*++t_wp)) == RPAREN) |
return 0; /* missing expression */ |
res = oexpr(nn); |
if (t_lex(*++t_wp) != RPAREN) |
syntax(NULL, "closing paren expected"); |
return res; |
} |
if (t_wp_op && t_wp_op->op_type == UNOP) { |
/* unary expression */ |
if (*++t_wp == NULL) |
syntax(t_wp_op->op_text, "argument expected"); |
switch (n) { |
case STREZ: |
return strlen(*t_wp) == 0; |
case STRNZ: |
return strlen(*t_wp) != 0; |
case FILTT: |
return isatty(getn(*t_wp)); |
default: |
return filstat(*t_wp, n); |
} |
} |
if (t_lex(t_wp[1]), t_wp_op && t_wp_op->op_type == BINOP) { |
return binop(); |
} |
return strlen(*t_wp) > 0; |
} |
static int |
binop() |
{ |
const char *opnd1, *opnd2; |
struct t_op const *op; |
opnd1 = *t_wp; |
(void) t_lex(*++t_wp); |
op = t_wp_op; |
if ((opnd2 = *++t_wp) == (char *)0) |
syntax(op->op_text, "argument expected"); |
switch (op->op_num) { |
case STREQ: |
return strcmp(opnd1, opnd2) == 0; |
case STRNE: |
return strcmp(opnd1, opnd2) != 0; |
case STRLT: |
return strcmp(opnd1, opnd2) < 0; |
case STRGT: |
return strcmp(opnd1, opnd2) > 0; |
case INTEQ: |
return getn(opnd1) == getn(opnd2); |
case INTNE: |
return getn(opnd1) != getn(opnd2); |
case INTGE: |
return getn(opnd1) >= getn(opnd2); |
case INTGT: |
return getn(opnd1) > getn(opnd2); |
case INTLE: |
return getn(opnd1) <= getn(opnd2); |
case INTLT: |
return getn(opnd1) < getn(opnd2); |
case FILNT: |
return newerf (opnd1, opnd2); |
case FILOT: |
return olderf (opnd1, opnd2); |
case FILEQ: |
return equalf (opnd1, opnd2); |
default: |
abort(); |
/* NOTREACHED */ |
} |
} |
static int |
filstat(nm, mode) |
char *nm; |
enum token mode; |
{ |
struct stat s; |
if (mode == FILSYM ? lstat(nm, &s) : stat(nm, &s)) |
return 0; |
switch (mode) { |
case FILRD: |
return test_eaccess(nm, R_OK) == 0; |
case FILWR: |
return test_eaccess(nm, W_OK) == 0; |
case FILEX: |
return test_eaccess(nm, X_OK) == 0; |
case FILEXIST: |
return 1; |
case FILREG: |
return S_ISREG(s.st_mode); |
case FILDIR: |
return S_ISDIR(s.st_mode); |
case FILCDEV: |
return S_ISCHR(s.st_mode); |
case FILBDEV: |
return S_ISBLK(s.st_mode); |
case FILFIFO: |
return S_ISFIFO(s.st_mode); |
case FILSOCK: |
return S_ISSOCK(s.st_mode); |
case FILSYM: |
return S_ISLNK(s.st_mode); |
case FILSUID: |
return (s.st_mode & S_ISUID) != 0; |
case FILSGID: |
return (s.st_mode & S_ISGID) != 0; |
case FILSTCK: |
return (s.st_mode & S_ISVTX) != 0; |
case FILGZ: |
return s.st_size > (off_t)0; |
case FILUID: |
return s.st_uid == geteuid(); |
case FILGID: |
return s.st_gid == getegid(); |
default: |
return 1; |
} |
} |
static enum token |
t_lex(s) |
char *s; |
{ |
struct t_op const *op = ops; |
if (s == 0) { |
t_wp_op = (struct t_op *)0; |
return EOI; |
} |
while (op->op_text) { |
if (strcmp(s, op->op_text) == 0) { |
if ((op->op_type == UNOP && isoperand()) || |
(op->op_num == LPAREN && *(t_wp+1) == 0)) |
break; |
t_wp_op = op; |
return op->op_num; |
} |
op++; |
} |
t_wp_op = (struct t_op *)0; |
return OPERAND; |
} |
static int |
isoperand() |
{ |
struct t_op const *op = ops; |
char *s; |
char *t; |
if ((s = *(t_wp+1)) == 0) |
return 1; |
if ((t = *(t_wp+2)) == 0) |
return 0; |
while (op->op_text) { |
if (strcmp(s, op->op_text) == 0) |
return op->op_type == BINOP && |
(t[0] != ')' || t[1] != '\0'); |
op++; |
} |
return 0; |
} |
/* atoi with error detection */ |
static int |
getn(s) |
const char *s; |
{ |
char *p; |
long r; |
errno = 0; |
r = strtol(s, &p, 10); |
if (errno != 0) |
error("%s: out of range", s); |
while (isspace((unsigned char)*p)) |
p++; |
if (*p) |
error("%s: bad number", s); |
return (int) r; |
} |
static int |
newerf (f1, f2) |
const char *f1, *f2; |
{ |
struct stat b1, b2; |
return (stat (f1, &b1) == 0 && |
stat (f2, &b2) == 0 && |
b1.st_mtime > b2.st_mtime); |
} |
static int |
olderf (f1, f2) |
const char *f1, *f2; |
{ |
struct stat b1, b2; |
return (stat (f1, &b1) == 0 && |
stat (f2, &b2) == 0 && |
b1.st_mtime < b2.st_mtime); |
} |
static int |
equalf (f1, f2) |
const char *f1, *f2; |
{ |
struct stat b1, b2; |
return (stat (f1, &b1) == 0 && |
stat (f2, &b2) == 0 && |
b1.st_dev == b2.st_dev && |
b1.st_ino == b2.st_ino); |
} |
/* Do the same thing access(2) does, but use the effective uid and gid, |
and don't make the mistake of telling root that any file is |
executable. */ |
static int |
test_eaccess (path, mode) |
char *path; |
int mode; |
{ |
struct stat st; |
int euid = geteuid(); |
if (stat (path, &st) < 0) |
return (-1); |
if (euid == 0) { |
/* Root can read or write any file. */ |
if (mode != X_OK) |
return (0); |
/* Root can execute any file that has any one of the execute |
bits set. */ |
if (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) |
return (0); |
} |
if (st.st_uid == euid) /* owner */ |
mode <<= 6; |
else if (bash_group_member (st.st_gid)) |
mode <<= 3; |
if (st.st_mode & mode) |
return (0); |
return (-1); |
} |
static void |
initialize_group_array () |
{ |
ngroups = getgroups(0, NULL); |
group_array = malloc(ngroups * sizeof(gid_t)); |
if (!group_array) |
error(strerror(ENOMEM)); |
getgroups(ngroups, group_array); |
} |
/* Return non-zero if GID is one that we have in our groups list. */ |
static int |
bash_group_member (gid) |
gid_t gid; |
{ |
register int i; |
/* Short-circuit if possible, maybe saving a call to getgroups(). */ |
if (gid == getgid() || gid == getegid()) |
return (1); |
if (ngroups == 0) |
initialize_group_array (); |
/* Search through the list looking for GID. */ |
for (i = 0; i < ngroups; i++) |
if (gid == group_array[i]) |
return (1); |
return (0); |
} |
/branches/dd/uspace/app/ash/bltin/times.c |
---|
0,0 → 1,30 |
#ifdef _GNU_SOURCE |
/* |
* Copyright (c) 1999 Herbert Xu <herbert@debian.org> |
* This file contains code for the times builtin. |
* $Id: ash-0.4.0-cumulative_fixes-1.patch,v 1.1 2004/06/04 10:32:01 jim Exp $ |
*/ |
#include <stdio.h> |
#include <sys/times.h> |
#include <unistd.h> |
#define main timescmd |
int main() { |
struct tms buf; |
long int clk_tck = sysconf(_SC_CLK_TCK); |
times(&buf); |
printf("%dm%fs %dm%fs\n%dm%fs %dm%fs\n", |
(int) (buf.tms_utime / clk_tck / 60), |
((double) buf.tms_utime) / clk_tck, |
(int) (buf.tms_stime / clk_tck / 60), |
((double) buf.tms_stime) / clk_tck, |
(int) (buf.tms_cutime / clk_tck / 60), |
((double) buf.tms_cutime) / clk_tck, |
(int) (buf.tms_cstime / clk_tck / 60), |
((double) buf.tms_cstime) / clk_tck); |
return 0; |
} |
#endif /* _GNU_SOURCE */ |
/branches/dd/uspace/app/ash/bltin/echo.1 |
---|
0,0 → 1,113 |
.\" $NetBSD: echo.1,v 1.9 1999/03/22 18:30:47 garbled Exp $ |
.\" |
.\" Copyright (c) 1991, 1993 |
.\" The Regents of the University of California. All rights reserved. |
.\" |
.\" This code is derived from software contributed to Berkeley by |
.\" Kenneth Almquist. |
.\" Copyright 1989 by Kenneth Almquist |
.\" |
.\" Redistribution and use in source and binary forms, with or without |
.\" modification, are permitted provided that the following conditions |
.\" are met: |
.\" 1. Redistributions of source code must retain the above copyright |
.\" notice, this list of conditions and the following disclaimer. |
.\" 2. Redistributions in binary form must reproduce the above copyright |
.\" notice, this list of conditions and the following disclaimer in the |
.\" documentation and/or other materials provided with the distribution. |
.\" 3. All advertising materials mentioning features or use of this software |
.\" must display the following acknowledgement: |
.\" This product includes software developed by the University of |
.\" California, Berkeley and its contributors. |
.\" 4. Neither the name of the University nor the names of its contributors |
.\" may be used to endorse or promote products derived from this software |
.\" without specific prior written permission. |
.\" |
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
.\" SUCH DAMAGE. |
.\" |
.\" @(#)echo.1 8.1 (Berkeley) 5/31/93 |
.\" |
.Dd May 31, 1993 |
.Dt ECHO 1 |
.Os |
.Sh NAME |
.Nm echo |
.Nd produce message in a shell script |
.Sh SYNOPSIS |
.Nm |
.Op Fl n | Fl e |
.Ar args... |
.Sh DESCRIPTION |
.Nm |
prints its arguments on the standard output, separated by spaces. |
Unless the |
.Fl n |
option is present, a newline is output following the arguments. |
The |
.Fl e |
option causes |
.Nm |
to treat the escape sequences specially, as described in the following |
paragraph. |
The |
.Fl e |
option is the default, and is provided solely for compatibility with |
other systems. |
Only one of the options |
.Fl n |
and |
.Fl e |
may be given. |
.Pp |
If any of the following sequences of characters is encountered during |
output, the sequence is not output. Instead, the specified action is |
performed: |
.Bl -tag -width indent |
.It Li \eb |
A backspace character is output. |
.It Li \ec |
Subsequent output is suppressed. This is normally used at the end of the |
last argument to suppress the trailing newline that |
.Nm |
would otherwise output. |
.It Li \ef |
Output a form feed. |
.It Li \en |
Output a newline character. |
.It Li \er |
Output a carriage return. |
.It Li \et |
Output a (horizontal) tab character. |
.It Li \ev |
Output a vertical tab. |
.It Li \e0 Ns Ar digits |
Output the character whose value is given by zero to three digits. |
If there are zero digits, a nul character is output. |
.It Li \e\e |
Output a backslash. |
.El |
.Sh HINTS |
Remember that backslash is special to the shell and needs to be escaped. |
To output a message to standard error, say |
.Pp |
.D1 echo message >&2 |
.Sh BUGS |
The octal character escape mechanism |
.Pq Li \e0 Ns Ar digits |
differs from the |
C language mechanism. |
.Pp |
There is no way to force |
.Nm |
to treat its arguments literally, rather than interpreting them as |
options and escape sequences. |
/branches/dd/uspace/app/ash/bltin/bltin.h |
---|
0,0 → 1,81 |
/* $NetBSD: bltin.h,v 1.9 1997/07/04 21:02:29 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)bltin.h 8.1 (Berkeley) 5/31/93 |
*/ |
/* |
* This file is included by programs which are optionally built into the |
* shell. If SHELL is defined, we try to map the standard UNIX library |
* routines to ash routines using defines. |
*/ |
#include "../shell.h" |
#include "../mystring.h" |
#include "../memalloc.h" |
#ifdef SHELL |
#include "../output.h" |
#ifndef _GNU_SOURCE |
#define stdout out1 |
#define stderr out2 |
#define printf out1fmt |
#define putc(c, file) outc(c, file) |
#define putchar(c) out1c(c) |
#define fprintf outfmt |
#define fputs outstr |
#define fflush flushout |
#define warnx(a, b, c) { \ |
char buf[64]; \ |
(void)snprintf(buf, sizeof(buf), a, b, c); \ |
error("%s", buf); \ |
} |
#endif |
#define INITARGS(argv) |
#else |
#undef NULL |
#include <stdio.h> |
#undef main |
#define INITARGS(argv) if ((commandname = argv[0]) == NULL) {fputs("Argc is zero\n", stderr); exit(2);} else |
#endif |
pointer stalloc __P((int)); |
void error __P((char *, ...)); |
int echocmd __P((int, char **)); |
extern char *commandname; |
/branches/dd/uspace/app/ash/memalloc.c |
---|
0,0 → 1,329 |
/* $NetBSD: memalloc.c,v 1.23 2000/11/01 19:56:01 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)memalloc.c 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: memalloc.c,v 1.23 2000/11/01 19:56:01 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdlib.h> |
#include <unistd.h> |
#include "shell.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "machdep.h" |
#include "mystring.h" |
/* |
* Like malloc, but returns an error when out of space. |
*/ |
pointer |
ckmalloc(nbytes) |
int nbytes; |
{ |
pointer p; |
INTOFF; |
p = malloc(nbytes); |
INTON; |
if (p == NULL) |
error("Out of space"); |
return p; |
} |
/* |
* Same for realloc. |
*/ |
pointer |
ckrealloc(p, nbytes) |
pointer p; |
int nbytes; |
{ |
if ((p = realloc(p, nbytes)) == NULL) |
error("Out of space"); |
return p; |
} |
/* |
* Make a copy of a string in safe storage. |
*/ |
char * |
savestr(s) |
char *s; |
{ |
char *p; |
p = ckmalloc(strlen(s) + 1); |
scopy(s, p); |
return p; |
} |
/* |
* Parse trees for commands are allocated in lifo order, so we use a stack |
* to make this more efficient, and also to avoid all sorts of exception |
* handling code to handle interrupts in the middle of a parse. |
* |
* The size 504 was chosen because the Ultrix malloc handles that size |
* well. |
*/ |
#define MINSIZE 504 /* minimum size of a block */ |
struct stack_block { |
struct stack_block *prev; |
char space[MINSIZE]; |
}; |
struct stack_block stackbase; |
struct stack_block *stackp = &stackbase; |
struct stackmark *markp; |
char *stacknxt = stackbase.space; |
int stacknleft = MINSIZE; |
int sstrnleft; |
int herefd = -1; |
pointer |
stalloc(nbytes) |
int nbytes; |
{ |
char *p; |
nbytes = ALIGN(nbytes); |
if (nbytes > stacknleft) { |
int blocksize; |
struct stack_block *sp; |
blocksize = nbytes; |
if (blocksize < MINSIZE) |
blocksize = MINSIZE; |
INTOFF; |
sp = ckmalloc(sizeof(struct stack_block) - MINSIZE + blocksize); |
sp->prev = stackp; |
stacknxt = sp->space; |
stacknleft = blocksize; |
stackp = sp; |
INTON; |
} |
p = stacknxt; |
stacknxt += nbytes; |
stacknleft -= nbytes; |
return p; |
} |
void |
stunalloc(p) |
pointer p; |
{ |
if (p == NULL) { /*DEBUG */ |
write(2, "stunalloc\n", 10); |
abort(); |
} |
stacknleft += stacknxt - (char *)p; |
stacknxt = p; |
} |
void |
setstackmark(mark) |
struct stackmark *mark; |
{ |
mark->stackp = stackp; |
mark->stacknxt = stacknxt; |
mark->stacknleft = stacknleft; |
mark->marknext = markp; |
markp = mark; |
} |
void |
popstackmark(mark) |
struct stackmark *mark; |
{ |
struct stack_block *sp; |
INTOFF; |
markp = mark->marknext; |
while (stackp != mark->stackp) { |
sp = stackp; |
stackp = sp->prev; |
ckfree(sp); |
} |
stacknxt = mark->stacknxt; |
stacknleft = mark->stacknleft; |
INTON; |
} |
/* |
* When the parser reads in a string, it wants to stick the string on the |
* stack and only adjust the stack pointer when it knows how big the |
* string is. Stackblock (defined in stack.h) returns a pointer to a block |
* of space on top of the stack and stackblocklen returns the length of |
* this block. Growstackblock will grow this space by at least one byte, |
* possibly moving it (like realloc). Grabstackblock actually allocates the |
* part of the block that has been used. |
*/ |
void |
growstackblock() { |
char *p; |
int newlen = ALIGN(stacknleft * 2 + 100); |
char *oldspace = stacknxt; |
int oldlen = stacknleft; |
struct stack_block *sp; |
struct stack_block *oldstackp; |
if (stacknxt == stackp->space && stackp != &stackbase) { |
INTOFF; |
oldstackp = stackp; |
sp = stackp; |
stackp = sp->prev; |
sp = ckrealloc((pointer)sp, sizeof(struct stack_block) - MINSIZE + newlen); |
sp->prev = stackp; |
stackp = sp; |
stacknxt = sp->space; |
stacknleft = newlen; |
{ |
/* Stack marks pointing to the start of the old block |
* must be relocated to point to the new block |
*/ |
struct stackmark *xmark; |
xmark = markp; |
while (xmark != NULL && xmark->stackp == oldstackp) { |
xmark->stackp = stackp; |
xmark->stacknxt = stacknxt; |
xmark->stacknleft = stacknleft; |
xmark = xmark->marknext; |
} |
} |
INTON; |
} else { |
p = stalloc(newlen); |
memcpy(p, oldspace, oldlen); |
stacknxt = p; /* free the space */ |
stacknleft += newlen; /* we just allocated */ |
} |
} |
void |
grabstackblock(len) |
int len; |
{ |
len = ALIGN(len); |
stacknxt += len; |
stacknleft -= len; |
} |
/* |
* The following routines are somewhat easier to use that the above. |
* The user declares a variable of type STACKSTR, which may be declared |
* to be a register. The macro STARTSTACKSTR initializes things. Then |
* the user uses the macro STPUTC to add characters to the string. In |
* effect, STPUTC(c, p) is the same as *p++ = c except that the stack is |
* grown as necessary. When the user is done, she can just leave the |
* string there and refer to it using stackblock(). Or she can allocate |
* the space for it using grabstackstr(). If it is necessary to allow |
* someone else to use the stack temporarily and then continue to grow |
* the string, the user should use grabstack to allocate the space, and |
* then call ungrabstr(p) to return to the previous mode of operation. |
* |
* USTPUTC is like STPUTC except that it doesn't check for overflow. |
* CHECKSTACKSPACE can be called before USTPUTC to ensure that there |
* is space for at least one character. |
*/ |
char * |
growstackstr() { |
int len = stackblocksize(); |
if (herefd >= 0 && len >= 1024) { |
xwrite(herefd, stackblock(), len); |
sstrnleft = len - 1; |
return stackblock(); |
} |
growstackblock(); |
sstrnleft = stackblocksize() - len - 1; |
return stackblock() + len; |
} |
/* |
* Called from CHECKSTRSPACE. |
*/ |
char * |
makestrspace() { |
int len = stackblocksize() - sstrnleft; |
growstackblock(); |
sstrnleft = stackblocksize() - len; |
return stackblock() + len; |
} |
void |
ungrabstackstr(s, p) |
char *s; |
char *p; |
{ |
stacknleft += stacknxt - s; |
stacknxt = s; |
sstrnleft = stacknleft - (p - s); |
} |
/branches/dd/uspace/app/ash/alias.c |
---|
0,0 → 1,267 |
/* $NetBSD: alias.c,v 1.10 1998/05/20 00:27:56 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
//#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)alias.c 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: alias.c,v 1.10 1998/05/20 00:27:56 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdlib.h> |
#include "shell.h" |
#include "input.h" |
#include "output.h" |
#include "error.h" |
#include "memalloc.h" |
#include "mystring.h" |
#include "alias.h" |
#include "options.h" /* XXX for argptr (should remove?) */ |
#define ATABSIZE 39 |
struct alias *atab[ATABSIZE]; |
STATIC void setalias (char *, char *); |
STATIC int unalias (char *); |
STATIC struct alias **hashalias (char *); |
STATIC |
void |
setalias(char *name, char *val) |
{ |
struct alias *ap, **app; |
app = hashalias(name); |
for (ap = *app; ap; ap = ap->next) { |
if (equal(name, ap->name)) { |
INTOFF; |
ckfree(ap->val); |
ap->val = savestr(val); |
INTON; |
return; |
} |
} |
/* not found */ |
INTOFF; |
ap = ckmalloc(sizeof (struct alias)); |
ap->name = savestr(name); |
/* |
* XXX - HACK: in order that the parser will not finish reading the |
* alias value off the input before processing the next alias, we |
* dummy up an extra space at the end of the alias. This is a crock |
* and should be re-thought. The idea (if you feel inclined to help) |
* is to avoid alias recursions. The mechanism used is: when |
* expanding an alias, the value of the alias is pushed back on the |
* input as a string and a pointer to the alias is stored with the |
* string. The alias is marked as being in use. When the input |
* routine finishes reading the string, it markes the alias not |
* in use. The problem is synchronization with the parser. Since |
* it reads ahead, the alias is marked not in use before the |
* resulting token(s) is next checked for further alias sub. The |
* H A C K is that we add a little fluff after the alias value |
* so that the string will not be exhausted. This is a good |
* idea ------- ***NOT*** |
*/ |
#ifdef notyet |
ap->val = savestr(val); |
#else /* hack */ |
{ |
int len = strlen(val); |
ap->val = ckmalloc(len + 2); |
memcpy(ap->val, val, len); |
ap->val[len] = ' '; /* fluff */ |
ap->val[len+1] = '\0'; |
} |
#endif |
ap->next = *app; |
*app = ap; |
INTON; |
} |
STATIC int |
unalias(name) |
char *name; |
{ |
struct alias *ap, **app; |
app = hashalias(name); |
for (ap = *app; ap; app = &(ap->next), ap = ap->next) { |
if (equal(name, ap->name)) { |
/* |
* if the alias is currently in use (i.e. its |
* buffer is being used by the input routine) we |
* just null out the name instead of freeing it. |
* We could clear it out later, but this situation |
* is so rare that it hardly seems worth it. |
*/ |
if (ap->flag & ALIASINUSE) |
*ap->name = '\0'; |
else { |
INTOFF; |
*app = ap->next; |
ckfree(ap->name); |
ckfree(ap->val); |
ckfree(ap); |
INTON; |
} |
return (0); |
} |
} |
return (1); |
} |
#ifdef mkinit |
MKINIT void rmaliases (void); |
SHELLPROC { |
rmaliases(); |
} |
#endif |
void |
rmaliases() { |
struct alias *ap, *tmp; |
int i; |
INTOFF; |
for (i = 0; i < ATABSIZE; i++) { |
ap = atab[i]; |
atab[i] = NULL; |
while (ap) { |
ckfree(ap->name); |
ckfree(ap->val); |
tmp = ap; |
ap = ap->next; |
ckfree(tmp); |
} |
} |
INTON; |
} |
struct alias * |
lookupalias(name, check) |
char *name; |
int check; |
{ |
struct alias *ap = *hashalias(name); |
for (; ap; ap = ap->next) { |
if (equal(name, ap->name)) { |
if (check && (ap->flag & ALIASINUSE)) |
return (NULL); |
return (ap); |
} |
} |
return (NULL); |
} |
/* |
* TODO - sort output |
*/ |
int |
aliascmd(argc, argv) |
int argc; |
char **argv; |
{ |
char *n, *v; |
int ret = 0; |
struct alias *ap; |
if (argc == 1) { |
int i; |
for (i = 0; i < ATABSIZE; i++) |
for (ap = atab[i]; ap; ap = ap->next) { |
if (*ap->name != '\0') |
out1fmt("alias %s=%s\n", ap->name, ap->val); |
} |
return (0); |
} |
while ((n = *++argv) != NULL) { |
if ((v = strchr(n+1, '=')) == NULL) { /* n+1: funny ksh stuff */ |
if ((ap = lookupalias(n, 0)) == NULL) { |
outfmt(out2, "alias: %s not found\n", n); |
ret = 1; |
} else |
out1fmt("alias %s=%s\n", n, ap->val); |
} |
else { |
*v++ = '\0'; |
setalias(n, v); |
} |
} |
return (ret); |
} |
int |
unaliascmd(argc, argv) |
int argc; |
char **argv; |
{ |
int i; |
while ((i = nextopt("a")) != '\0') { |
if (i == 'a') { |
rmaliases(); |
return (0); |
} |
} |
for (i = 0; *argptr; argptr++) |
i = unalias(*argptr); |
return (i); |
} |
STATIC struct alias ** |
hashalias(p) |
char *p; |
{ |
unsigned int hashval; |
hashval = *p << 4; |
while (*p) |
hashval+= *p++; |
return &atab[hashval % ATABSIZE]; |
} |
/branches/dd/uspace/app/ash/exec.h |
---|
0,0 → 1,79 |
/* $NetBSD: exec.h,v 1.17 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)exec.h 8.3 (Berkeley) 6/8/95 |
*/ |
/* values of cmdtype */ |
#define CMDUNKNOWN -1 /* no entry in table for command */ |
#define CMDNORMAL 0 /* command is an executable program */ |
#define CMDBUILTIN 1 /* command is a shell builtin */ |
#define CMDFUNCTION 2 /* command is a shell function */ |
struct cmdentry { |
int cmdtype; |
union param { |
int index; |
union node *func; |
} u; |
}; |
#define DO_ERR 1 /* find_command prints errors */ |
#define DO_ABS 2 /* find_command checks absolute paths */ |
#define DO_NOFUN 4 /* find_command ignores functions */ |
#define DO_BRUTE 8 /* find_command ignores hash table */ |
extern const char *pathopt; /* set by padvance */ |
extern int exerrno; /* last exec error */ |
void shellexec (char **, char **, const char *, int) |
__attribute__((noreturn)); |
char *padvance (const char **, const char *); |
int hashcmd (int, char **); |
void find_command (char *, struct cmdentry *, int, const char *); |
int find_builtin (char *); |
void hashcd (void); |
void changepath (const char *); |
void deletefuncs (void); |
void getcmdentry (char *, struct cmdentry *); |
void addcmdentry (char *, struct cmdentry *); |
void defun (char *, union node *); |
int unsetfunc (char *); |
int typecmd (int, char **); |
int commandcmd (int, char **); |
/branches/dd/uspace/app/ash/nodes.c.pat |
---|
0,0 → 1,169 |
/* $NetBSD: nodes.c.pat,v 1.8 1997/04/11 23:03:09 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)nodes.c.pat 8.2 (Berkeley) 5/4/95 |
*/ |
#include <stdlib.h> |
/* |
* Routine for dealing with parsed shell commands. |
*/ |
#include "shell.h" |
#include "nodes.h" |
#include "memalloc.h" |
#include "machdep.h" |
#include "mystring.h" |
int funcblocksize; /* size of structures in function */ |
int funcstringsize; /* size of strings in node */ |
pointer funcblock; /* block to allocate function from */ |
char *funcstring; /* block to allocate strings from */ |
%SIZES |
STATIC void calcsize (union node *); |
STATIC void sizenodelist (struct nodelist *); |
STATIC union node *copynode (union node *); |
STATIC struct nodelist *copynodelist (struct nodelist *); |
STATIC char *nodesavestr (char *); |
/* |
* Make a copy of a parse tree. |
*/ |
union node * |
copyfunc(n) |
union node *n; |
{ |
if (n == NULL) |
return NULL; |
funcblocksize = 0; |
funcstringsize = 0; |
calcsize(n); |
funcblock = ckmalloc(funcblocksize + funcstringsize); |
funcstring = (char *) funcblock + funcblocksize; |
return copynode(n); |
} |
STATIC void |
calcsize(n) |
union node *n; |
{ |
%CALCSIZE |
} |
STATIC void |
sizenodelist(lp) |
struct nodelist *lp; |
{ |
while (lp) { |
funcblocksize += ALIGN(sizeof(struct nodelist)); |
calcsize(lp->n); |
lp = lp->next; |
} |
} |
STATIC union node * |
copynode(n) |
union node *n; |
{ |
union node *new; |
%COPY |
return new; |
} |
STATIC struct nodelist * |
copynodelist(lp) |
struct nodelist *lp; |
{ |
struct nodelist *start; |
struct nodelist **lpp; |
lpp = &start; |
while (lp) { |
*lpp = funcblock; |
funcblock = (char *) funcblock + ALIGN(sizeof(struct nodelist)); |
(*lpp)->n = copynode(lp->n); |
lp = lp->next; |
lpp = &(*lpp)->next; |
} |
*lpp = NULL; |
return start; |
} |
STATIC char * |
nodesavestr(s) |
char *s; |
{ |
register char *p = s; |
register char *q = funcstring; |
char *rtn = funcstring; |
while ((*q++ = *p++) != '\0') |
continue; |
funcstring = q; |
return rtn; |
} |
/* |
* Free a parse tree. |
*/ |
void |
freefunc(n) |
union node *n; |
{ |
if (n) |
ckfree(n); |
} |
/branches/dd/uspace/app/ash/cd.h |
---|
0,0 → 1,39 |
/* $NetBSD: cd.h,v 1.2 1997/07/04 21:01:52 christos Exp $ */ |
/*- |
* Copyright (c) 1995 |
* The Regents of the University of California. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
*/ |
void getpwd (void); |
int cdcmd (int, char **); |
int pwdcmd (int, char **); |
/branches/dd/uspace/app/ash/parser.c |
---|
0,0 → 1,1559 |
/* $NetBSD: parser.c,v 1.45 2000/07/27 04:09:27 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)parser.c 8.7 (Berkeley) 5/16/95"; |
#else |
__RCSID("$NetBSD: parser.c,v 1.45 2000/07/27 04:09:27 cgd Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdlib.h> |
#include "shell.h" |
#include "parser.h" |
#include "nodes.h" |
#include "expand.h" /* defines rmescapes() */ |
#include "redir.h" /* defines copyfd() */ |
#include "syntax.h" |
#include "options.h" |
#include "input.h" |
#include "output.h" |
#include "var.h" |
#include "error.h" |
#include "memalloc.h" |
#include "mystring.h" |
#include "alias.h" |
#include "show.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#endif |
/* |
* Shell command parser. |
*/ |
#define EOFMARKLEN 79 |
/* values returned by readtoken */ |
#include "token.h" |
struct heredoc { |
struct heredoc *next; /* next here document in list */ |
union node *here; /* redirection node */ |
char *eofmark; /* string indicating end of input */ |
int striptabs; /* if set, strip leading tabs */ |
}; |
struct heredoc *heredoclist; /* list of here documents to read */ |
int parsebackquote; /* nonzero if we are inside backquotes */ |
int doprompt; /* if set, prompt the user */ |
int needprompt; /* true if interactive and at start of line */ |
int lasttoken; /* last token read */ |
MKINIT int tokpushback; /* last token pushed back */ |
char *wordtext; /* text of last word returned by readtoken */ |
MKINIT int checkkwd; /* 1 == check for kwds, 2 == also eat newlines */ |
struct nodelist *backquotelist; |
union node *redirnode; |
struct heredoc *heredoc; |
int quoteflag; /* set if (part of) last token was quoted */ |
int startlinno; /* line # where last token started */ |
STATIC union node *list (int); |
STATIC union node *andor (void); |
STATIC union node *pipeline (void); |
STATIC union node *command (void); |
STATIC union node *simplecmd (union node **, union node *); |
STATIC union node *makename (void); |
STATIC void parsefname (void); |
STATIC void parseheredoc (void); |
STATIC int peektoken (void); |
STATIC int readtoken (void); |
STATIC int xxreadtoken (void); |
STATIC int readtoken1 (int, char const *, char *, int); |
STATIC int noexpand (char *); |
STATIC void synexpect (int) __attribute__((noreturn)); |
STATIC void synerror (const char *) __attribute__((noreturn)); |
STATIC void setprompt (int); |
/* |
* Read and parse a command. Returns NEOF on end of file. (NULL is a |
* valid parse tree indicating a blank line.) |
*/ |
union node * |
parsecmd(int interact) |
{ |
int t; |
doprompt = interact; |
if (doprompt) |
setprompt(1); |
else |
setprompt(0); |
needprompt = 0; |
t = readtoken(); |
if (t == TEOF) |
return NEOF; |
if (t == TNL) |
return NULL; |
tokpushback++; |
return list(1); |
} |
STATIC union node * |
list(nlflag) |
int nlflag; |
{ |
union node *n1, *n2, *n3; |
int tok; |
checkkwd = 2; |
if (nlflag == 0 && tokendlist[peektoken()]) |
return NULL; |
n1 = NULL; |
for (;;) { |
n2 = andor(); |
tok = readtoken(); |
if (tok == TBACKGND) { |
if (n2->type == NCMD || n2->type == NPIPE) { |
n2->ncmd.backgnd = 1; |
} else if (n2->type == NREDIR) { |
n2->type = NBACKGND; |
} else { |
n3 = (union node *)stalloc(sizeof (struct nredir)); |
n3->type = NBACKGND; |
n3->nredir.n = n2; |
n3->nredir.redirect = NULL; |
n2 = n3; |
} |
} |
if (n1 == NULL) { |
n1 = n2; |
} |
else { |
n3 = (union node *)stalloc(sizeof (struct nbinary)); |
n3->type = NSEMI; |
n3->nbinary.ch1 = n1; |
n3->nbinary.ch2 = n2; |
n1 = n3; |
} |
switch (tok) { |
case TBACKGND: |
case TSEMI: |
tok = readtoken(); |
/* fall through */ |
case TNL: |
if (tok == TNL) { |
parseheredoc(); |
if (nlflag) |
return n1; |
} else { |
tokpushback++; |
} |
checkkwd = 2; |
if (tokendlist[peektoken()]) |
return n1; |
break; |
case TEOF: |
if (heredoclist) |
parseheredoc(); |
else |
pungetc(); /* push back EOF on input */ |
return n1; |
default: |
if (nlflag) |
synexpect(-1); |
tokpushback++; |
return n1; |
} |
} |
} |
STATIC union node * |
andor() { |
union node *n1, *n2, *n3; |
int t; |
checkkwd = 1; |
n1 = pipeline(); |
for (;;) { |
if ((t = readtoken()) == TAND) { |
t = NAND; |
} else if (t == TOR) { |
t = NOR; |
} else { |
tokpushback++; |
return n1; |
} |
checkkwd = 2; |
n2 = pipeline(); |
n3 = (union node *)stalloc(sizeof (struct nbinary)); |
n3->type = t; |
n3->nbinary.ch1 = n1; |
n3->nbinary.ch2 = n2; |
n1 = n3; |
} |
} |
STATIC union node * |
pipeline() { |
union node *n1, *n2, *pipenode; |
struct nodelist *lp, *prev; |
int negate; |
negate = 0; |
TRACE(("pipeline: entered\n")); |
if (readtoken() == TNOT) { |
negate = !negate; |
checkkwd = 1; |
} else |
tokpushback++; |
n1 = command(); |
if (readtoken() == TPIPE) { |
pipenode = (union node *)stalloc(sizeof (struct npipe)); |
pipenode->type = NPIPE; |
pipenode->npipe.backgnd = 0; |
lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); |
pipenode->npipe.cmdlist = lp; |
lp->n = n1; |
do { |
prev = lp; |
lp = (struct nodelist *)stalloc(sizeof (struct nodelist)); |
checkkwd = 2; |
lp->n = command(); |
prev->next = lp; |
} while (readtoken() == TPIPE); |
lp->next = NULL; |
n1 = pipenode; |
} |
tokpushback++; |
if (negate) { |
n2 = (union node *)stalloc(sizeof (struct nnot)); |
n2->type = NNOT; |
n2->nnot.com = n1; |
return n2; |
} else |
return n1; |
} |
STATIC union node * |
command() { |
union node *n1, *n2; |
union node *ap, **app; |
union node *cp, **cpp; |
union node *redir, **rpp; |
int t; |
redir = NULL; |
n1 = NULL; |
rpp = &redir; |
/* Check for redirection which may precede command */ |
while (readtoken() == TREDIR) { |
*rpp = n2 = redirnode; |
rpp = &n2->nfile.next; |
parsefname(); |
} |
tokpushback++; |
switch (readtoken()) { |
case TIF: |
n1 = (union node *)stalloc(sizeof (struct nif)); |
n1->type = NIF; |
n1->nif.test = list(0); |
if (readtoken() != TTHEN) |
synexpect(TTHEN); |
n1->nif.ifpart = list(0); |
n2 = n1; |
while (readtoken() == TELIF) { |
n2->nif.elsepart = (union node *)stalloc(sizeof (struct nif)); |
n2 = n2->nif.elsepart; |
n2->type = NIF; |
n2->nif.test = list(0); |
if (readtoken() != TTHEN) |
synexpect(TTHEN); |
n2->nif.ifpart = list(0); |
} |
if (lasttoken == TELSE) |
n2->nif.elsepart = list(0); |
else { |
n2->nif.elsepart = NULL; |
tokpushback++; |
} |
if (readtoken() != TFI) |
synexpect(TFI); |
checkkwd = 1; |
break; |
case TWHILE: |
case TUNTIL: { |
int got; |
n1 = (union node *)stalloc(sizeof (struct nbinary)); |
n1->type = (lasttoken == TWHILE)? NWHILE : NUNTIL; |
n1->nbinary.ch1 = list(0); |
if ((got=readtoken()) != TDO) { |
TRACE(("expecting DO got %s %s\n", tokname[got], got == TWORD ? wordtext : "")); |
synexpect(TDO); |
} |
n1->nbinary.ch2 = list(0); |
if (readtoken() != TDONE) |
synexpect(TDONE); |
checkkwd = 1; |
break; |
} |
case TFOR: |
if (readtoken() != TWORD || quoteflag || ! goodname(wordtext)) |
synerror("Bad for loop variable"); |
n1 = (union node *)stalloc(sizeof (struct nfor)); |
n1->type = NFOR; |
n1->nfor.var = wordtext; |
if (readtoken() == TWORD && ! quoteflag && equal(wordtext, "in")) { |
app = ≈ |
while (readtoken() == TWORD) { |
n2 = (union node *)stalloc(sizeof (struct narg)); |
n2->type = NARG; |
n2->narg.text = wordtext; |
n2->narg.backquote = backquotelist; |
*app = n2; |
app = &n2->narg.next; |
} |
*app = NULL; |
n1->nfor.args = ap; |
if (lasttoken != TNL && lasttoken != TSEMI) |
synexpect(-1); |
} else { |
static char argvars[5] = {CTLVAR, VSNORMAL|VSQUOTE, |
'@', '=', '\0'}; |
n2 = (union node *)stalloc(sizeof (struct narg)); |
n2->type = NARG; |
n2->narg.text = argvars; |
n2->narg.backquote = NULL; |
n2->narg.next = NULL; |
n1->nfor.args = n2; |
/* |
* Newline or semicolon here is optional (but note |
* that the original Bourne shell only allowed NL). |
*/ |
if (lasttoken != TNL && lasttoken != TSEMI) |
tokpushback++; |
} |
checkkwd = 2; |
if ((t = readtoken()) == TDO) |
t = TDONE; |
else if (t == TBEGIN) |
t = TEND; |
else |
synexpect(-1); |
n1->nfor.body = list(0); |
if (readtoken() != t) |
synexpect(t); |
checkkwd = 1; |
break; |
case TCASE: |
n1 = (union node *)stalloc(sizeof (struct ncase)); |
n1->type = NCASE; |
if (readtoken() != TWORD) |
synexpect(TWORD); |
n1->ncase.expr = n2 = (union node *)stalloc(sizeof (struct narg)); |
n2->type = NARG; |
n2->narg.text = wordtext; |
n2->narg.backquote = backquotelist; |
n2->narg.next = NULL; |
while (readtoken() == TNL); |
if (lasttoken != TWORD || ! equal(wordtext, "in")) |
synerror("expecting \"in\""); |
cpp = &n1->ncase.cases; |
checkkwd = 2, readtoken(); |
do { |
if (lasttoken == TLP) |
readtoken(); |
*cpp = cp = (union node *)stalloc(sizeof (struct nclist)); |
cp->type = NCLIST; |
app = &cp->nclist.pattern; |
for (;;) { |
*app = ap = (union node *)stalloc(sizeof (struct narg)); |
ap->type = NARG; |
ap->narg.text = wordtext; |
ap->narg.backquote = backquotelist; |
if (checkkwd = 2, readtoken() != TPIPE) |
break; |
app = &ap->narg.next; |
readtoken(); |
} |
ap->narg.next = NULL; |
if (lasttoken != TRP) |
synexpect(TRP); |
cp->nclist.body = list(0); |
checkkwd = 2; |
if ((t = readtoken()) != TESAC) { |
if (t != TENDCASE) |
synexpect(TENDCASE); |
else |
checkkwd = 2, readtoken(); |
} |
cpp = &cp->nclist.next; |
} while(lasttoken != TESAC); |
*cpp = NULL; |
checkkwd = 1; |
break; |
case TLP: |
n1 = (union node *)stalloc(sizeof (struct nredir)); |
n1->type = NSUBSHELL; |
n1->nredir.n = list(0); |
n1->nredir.redirect = NULL; |
if (readtoken() != TRP) |
synexpect(TRP); |
checkkwd = 1; |
break; |
case TBEGIN: |
n1 = list(0); |
if (readtoken() != TEND) |
synexpect(TEND); |
checkkwd = 1; |
break; |
/* Handle an empty command like other simple commands. */ |
case TSEMI: |
case TAND: |
case TOR: |
case TNL: |
case TEOF: |
case TRP: |
case TBACKGND: |
/* |
* An empty command before a ; doesn't make much sense, and |
* should certainly be disallowed in the case of `if ;'. |
*/ |
if (!redir) |
synexpect(-1); |
case TWORD: |
tokpushback++; |
n1 = simplecmd(rpp, redir); |
return n1; |
default: |
synexpect(-1); |
/* NOTREACHED */ |
} |
/* Now check for redirection which may follow command */ |
while (readtoken() == TREDIR) { |
*rpp = n2 = redirnode; |
rpp = &n2->nfile.next; |
parsefname(); |
} |
tokpushback++; |
*rpp = NULL; |
if (redir) { |
if (n1->type != NSUBSHELL) { |
n2 = (union node *)stalloc(sizeof (struct nredir)); |
n2->type = NREDIR; |
n2->nredir.n = n1; |
n1 = n2; |
} |
n1->nredir.redirect = redir; |
} |
return n1; |
} |
STATIC union node * |
simplecmd(rpp, redir) |
union node **rpp, *redir; |
{ |
union node *args, **app; |
union node **orig_rpp = rpp; |
union node *n = NULL; |
/* If we don't have any redirections already, then we must reset */ |
/* rpp to be the address of the local redir variable. */ |
if (redir == 0) |
rpp = &redir; |
args = NULL; |
app = &args; |
/* |
* We save the incoming value, because we need this for shell |
* functions. There can not be a redirect or an argument between |
* the function name and the open parenthesis. |
*/ |
orig_rpp = rpp; |
for (;;) { |
if (readtoken() == TWORD) { |
n = (union node *)stalloc(sizeof (struct narg)); |
n->type = NARG; |
n->narg.text = wordtext; |
n->narg.backquote = backquotelist; |
*app = n; |
app = &n->narg.next; |
} else if (lasttoken == TREDIR) { |
*rpp = n = redirnode; |
rpp = &n->nfile.next; |
parsefname(); /* read name of redirection file */ |
} else if (lasttoken == TLP && app == &args->narg.next |
&& rpp == orig_rpp) { |
/* We have a function */ |
if (readtoken() != TRP) |
synexpect(TRP); |
#ifdef notdef |
if (! goodname(n->narg.text)) |
synerror("Bad function name"); |
#endif |
n->type = NDEFUN; |
checkkwd = 2; |
n->narg.next = command(); |
return n; |
} else { |
tokpushback++; |
break; |
} |
} |
*app = NULL; |
*rpp = NULL; |
n = (union node *)stalloc(sizeof (struct ncmd)); |
n->type = NCMD; |
n->ncmd.backgnd = 0; |
n->ncmd.args = args; |
n->ncmd.redirect = redir; |
return n; |
} |
STATIC union node * |
makename() { |
union node *n; |
n = (union node *)stalloc(sizeof (struct narg)); |
n->type = NARG; |
n->narg.next = NULL; |
n->narg.text = wordtext; |
n->narg.backquote = backquotelist; |
return n; |
} |
void fixredir(union node *n, const char *text, int err) |
{ |
TRACE(("Fix redir %s %d\n", text, err)); |
if (!err) |
n->ndup.vname = NULL; |
if (is_digit(text[0]) && text[1] == '\0') |
n->ndup.dupfd = digit_val(text[0]); |
else if (text[0] == '-' && text[1] == '\0') |
n->ndup.dupfd = -1; |
else { |
if (err) |
synerror("Bad fd number"); |
else |
n->ndup.vname = makename(); |
} |
} |
STATIC void |
parsefname() { |
union node *n = redirnode; |
if (readtoken() != TWORD) |
synexpect(-1); |
if (n->type == NHERE) { |
struct heredoc *here = heredoc; |
struct heredoc *p; |
int i; |
if (quoteflag == 0) |
n->type = NXHERE; |
TRACE(("Here document %d\n", n->type)); |
if (here->striptabs) { |
while (*wordtext == '\t') |
wordtext++; |
} |
if (! noexpand(wordtext) || (i = strlen(wordtext)) == 0 || i > EOFMARKLEN) |
synerror("Illegal eof marker for << redirection"); |
rmescapes(wordtext); |
here->eofmark = wordtext; |
here->next = NULL; |
if (heredoclist == NULL) |
heredoclist = here; |
else { |
for (p = heredoclist ; p->next ; p = p->next); |
p->next = here; |
} |
} else if (n->type == NTOFD || n->type == NFROMFD) { |
fixredir(n, wordtext, 0); |
} else { |
n->nfile.fname = makename(); |
} |
} |
/* |
* Input any here documents. |
*/ |
STATIC void |
parseheredoc() { |
struct heredoc *here; |
union node *n; |
while (heredoclist) { |
here = heredoclist; |
heredoclist = here->next; |
if (needprompt) { |
setprompt(2); |
needprompt = 0; |
} |
readtoken1(pgetc(), here->here->type == NHERE? SQSYNTAX : DQSYNTAX, |
here->eofmark, here->striptabs); |
n = (union node *)stalloc(sizeof (struct narg)); |
n->narg.type = NARG; |
n->narg.next = NULL; |
n->narg.text = wordtext; |
n->narg.backquote = backquotelist; |
here->here->nhere.doc = n; |
} |
} |
STATIC int |
peektoken() { |
int t; |
t = readtoken(); |
tokpushback++; |
return (t); |
} |
STATIC int |
readtoken() { |
int t; |
int savecheckkwd = checkkwd; |
struct alias *ap; |
#ifdef DEBUG |
int alreadyseen = tokpushback; |
#endif |
top: |
t = xxreadtoken(); |
if (checkkwd) { |
/* |
* eat newlines |
*/ |
if (checkkwd == 2) { |
checkkwd = 0; |
while (t == TNL) { |
parseheredoc(); |
t = xxreadtoken(); |
} |
} else |
checkkwd = 0; |
/* |
* check for keywords and aliases |
*/ |
if (t == TWORD && !quoteflag) |
{ |
const char *const *pp; |
for (pp = parsekwd; *pp; pp++) { |
if (**pp == *wordtext && equal(*pp, wordtext)) |
{ |
lasttoken = t = pp - |
parsekwd + KWDOFFSET; |
TRACE(("keyword %s recognized\n", tokname[t])); |
goto out; |
} |
} |
if ((ap = lookupalias(wordtext, 1)) != NULL) { |
pushstring(ap->val, strlen(ap->val), ap); |
checkkwd = savecheckkwd; |
goto top; |
} |
} |
out: |
checkkwd = 0; |
} |
#ifdef DEBUG |
if (!alreadyseen) |
TRACE(("token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); |
else |
TRACE(("reread token %s %s\n", tokname[t], t == TWORD ? wordtext : "")); |
#endif |
return (t); |
} |
/* |
* Read the next input token. |
* If the token is a word, we set backquotelist to the list of cmds in |
* backquotes. We set quoteflag to true if any part of the word was |
* quoted. |
* If the token is TREDIR, then we set redirnode to a structure containing |
* the redirection. |
* In all cases, the variable startlinno is set to the number of the line |
* on which the token starts. |
* |
* [Change comment: here documents and internal procedures] |
* [Readtoken shouldn't have any arguments. Perhaps we should make the |
* word parsing code into a separate routine. In this case, readtoken |
* doesn't need to have any internal procedures, but parseword does. |
* We could also make parseoperator in essence the main routine, and |
* have parseword (readtoken1?) handle both words and redirection.] |
*/ |
#define RETURN(token) return lasttoken = token |
STATIC int |
xxreadtoken() { |
int c; |
if (tokpushback) { |
tokpushback = 0; |
return lasttoken; |
} |
if (needprompt) { |
setprompt(2); |
needprompt = 0; |
} |
startlinno = plinno; |
for (;;) { /* until token or start of word found */ |
c = pgetc_macro(); |
if (c == ' ' || c == '\t') |
continue; /* quick check for white space first */ |
switch (c) { |
case ' ': case '\t': |
continue; |
case '#': |
while ((c = pgetc()) != '\n' && c != PEOF); |
pungetc(); |
continue; |
case '\\': |
if (pgetc() == '\n') { |
startlinno = ++plinno; |
if (doprompt) |
setprompt(2); |
else |
setprompt(0); |
continue; |
} |
pungetc(); |
goto breakloop; |
case '\n': |
plinno++; |
needprompt = doprompt; |
RETURN(TNL); |
case PEOF: |
RETURN(TEOF); |
case '&': |
if (pgetc() == '&') |
RETURN(TAND); |
pungetc(); |
RETURN(TBACKGND); |
case '|': |
if (pgetc() == '|') |
RETURN(TOR); |
pungetc(); |
RETURN(TPIPE); |
case ';': |
if (pgetc() == ';') |
RETURN(TENDCASE); |
pungetc(); |
RETURN(TSEMI); |
case '(': |
RETURN(TLP); |
case ')': |
RETURN(TRP); |
default: |
goto breakloop; |
} |
} |
breakloop: |
return readtoken1(c, BASESYNTAX, (char *)NULL, 0); |
#undef RETURN |
} |
/* |
* If eofmark is NULL, read a word or a redirection symbol. If eofmark |
* is not NULL, read a here document. In the latter case, eofmark is the |
* word which marks the end of the document and striptabs is true if |
* leading tabs should be stripped from the document. The argument firstc |
* is the first character of the input token or document. |
* |
* Because C does not have internal subroutines, I have simulated them |
* using goto's to implement the subroutine linkage. The following macros |
* will run code that appears at the end of readtoken1. |
*/ |
#define CHECKEND() {goto checkend; checkend_return:;} |
#define PARSEREDIR() {goto parseredir; parseredir_return:;} |
#define PARSESUB() {goto parsesub; parsesub_return:;} |
#define PARSEBACKQOLD() {oldstyle = 1; goto parsebackq; parsebackq_oldreturn:;} |
#define PARSEBACKQNEW() {oldstyle = 0; goto parsebackq; parsebackq_newreturn:;} |
#define PARSEARITH() {goto parsearith; parsearith_return:;} |
STATIC int |
readtoken1(firstc, syntax, eofmark, striptabs) |
int firstc; |
char const *syntax; |
char *eofmark; |
int striptabs; |
{ |
int c = firstc; |
char *out; |
int len; |
char line[EOFMARKLEN + 1]; |
struct nodelist *bqlist; |
int quotef; |
int dblquote; |
int varnest; /* levels of variables expansion */ |
int arinest; /* levels of arithmetic expansion */ |
int parenlevel; /* levels of parens in arithmetic */ |
int dqvarnest; /* levels of variables expansion within double quotes */ |
int oldstyle; |
char const *prevsyntax; /* syntax before arithmetic */ |
#if __GNUC__ |
/* Avoid longjmp clobbering */ |
(void) &out; |
(void) "ef; |
(void) &dblquote; |
(void) &varnest; |
(void) &arinest; |
(void) &parenlevel; |
(void) &dqvarnest; |
(void) &oldstyle; |
(void) &prevsyntax; |
(void) &syntax; |
#endif |
startlinno = plinno; |
dblquote = 0; |
if (syntax == DQSYNTAX) |
dblquote = 1; |
quotef = 0; |
bqlist = NULL; |
varnest = 0; |
arinest = 0; |
parenlevel = 0; |
dqvarnest = 0; |
STARTSTACKSTR(out); |
loop: { /* for each line, until end of word */ |
#if ATTY |
if (c == '\034' && doprompt |
&& attyset() && ! equal(termval(), "emacs")) { |
attyline(); |
if (syntax == BASESYNTAX) |
return readtoken(); |
c = pgetc(); |
goto loop; |
} |
#endif |
CHECKEND(); /* set c to PEOF if at end of here document */ |
for (;;) { /* until end of line or end of word */ |
CHECKSTRSPACE(3, out); /* permit 3 calls to USTPUTC */ |
switch(syntax[c]) { |
case CNL: /* '\n' */ |
if (syntax == BASESYNTAX) |
goto endword; /* exit outer loop */ |
USTPUTC(c, out); |
plinno++; |
if (doprompt) |
setprompt(2); |
else |
setprompt(0); |
c = pgetc(); |
goto loop; /* continue outer loop */ |
case CWORD: |
USTPUTC(c, out); |
break; |
case CCTL: |
if ((eofmark == NULL || dblquote) && |
dqvarnest == 0) |
USTPUTC(CTLESC, out); |
USTPUTC(c, out); |
break; |
case CBACK: /* backslash */ |
c = pgetc(); |
if (c == PEOF) { |
USTPUTC('\\', out); |
pungetc(); |
} else if (c == '\n') { |
if (doprompt) |
setprompt(2); |
else |
setprompt(0); |
} else { |
if (dblquote && c != '\\' && c != '`' && c != '$' |
&& (c != '"' || eofmark != NULL)) |
USTPUTC('\\', out); |
if (SQSYNTAX[c] == CCTL) |
USTPUTC(CTLESC, out); |
else if (eofmark == NULL) |
USTPUTC(CTLQUOTEMARK, out); |
USTPUTC(c, out); |
quotef++; |
} |
break; |
case CSQUOTE: |
if (eofmark == NULL) |
USTPUTC(CTLQUOTEMARK, out); |
syntax = SQSYNTAX; |
break; |
case CDQUOTE: |
if (eofmark == NULL) |
USTPUTC(CTLQUOTEMARK, out); |
syntax = DQSYNTAX; |
dblquote = 1; |
break; |
case CENDQUOTE: |
if (eofmark != NULL && arinest == 0 && |
varnest == 0) { |
USTPUTC(c, out); |
} else { |
if (arinest) { |
syntax = ARISYNTAX; |
dblquote = 0; |
} else if (eofmark == NULL && |
dqvarnest == 0) { |
syntax = BASESYNTAX; |
dblquote = 0; |
} |
quotef++; |
} |
break; |
case CVAR: /* '$' */ |
PARSESUB(); /* parse substitution */ |
break; |
case CENDVAR: /* '}' */ |
if (varnest > 0) { |
varnest--; |
if (dqvarnest > 0) { |
dqvarnest--; |
} |
USTPUTC(CTLENDVAR, out); |
} else { |
USTPUTC(c, out); |
} |
break; |
case CLP: /* '(' in arithmetic */ |
parenlevel++; |
USTPUTC(c, out); |
break; |
case CRP: /* ')' in arithmetic */ |
if (parenlevel > 0) { |
USTPUTC(c, out); |
--parenlevel; |
} else { |
if (pgetc() == ')') { |
if (--arinest == 0) { |
USTPUTC(CTLENDARI, out); |
syntax = prevsyntax; |
if (syntax == DQSYNTAX) |
dblquote = 1; |
else |
dblquote = 0; |
} else |
USTPUTC(')', out); |
} else { |
/* |
* unbalanced parens |
* (don't 2nd guess - no error) |
*/ |
pungetc(); |
USTPUTC(')', out); |
} |
} |
break; |
case CBQUOTE: /* '`' */ |
PARSEBACKQOLD(); |
break; |
case CEOF: |
goto endword; /* exit outer loop */ |
default: |
if (varnest == 0) |
goto endword; /* exit outer loop */ |
USTPUTC(c, out); |
} |
c = pgetc_macro(); |
} |
} |
endword: |
if (syntax == ARISYNTAX) |
synerror("Missing '))'"); |
if (syntax != BASESYNTAX && ! parsebackquote && eofmark == NULL) |
synerror("Unterminated quoted string"); |
if (varnest != 0) { |
startlinno = plinno; |
synerror("Missing '}'"); |
} |
USTPUTC('\0', out); |
len = out - stackblock(); |
out = stackblock(); |
if (eofmark == NULL) { |
if ((c == '>' || c == '<') |
&& quotef == 0 |
&& len <= 2 |
&& (*out == '\0' || is_digit(*out))) { |
PARSEREDIR(); |
return lasttoken = TREDIR; |
} else { |
pungetc(); |
} |
} |
quoteflag = quotef; |
backquotelist = bqlist; |
grabstackblock(len); |
wordtext = out; |
return lasttoken = TWORD; |
/* end of readtoken routine */ |
/* |
* Check to see whether we are at the end of the here document. When this |
* is called, c is set to the first character of the next input line. If |
* we are at the end of the here document, this routine sets the c to PEOF. |
*/ |
checkend: { |
if (eofmark) { |
if (striptabs) { |
while (c == '\t') |
c = pgetc(); |
} |
if (c == *eofmark) { |
if (pfgets(line, sizeof line) != NULL) { |
char *p, *q; |
p = line; |
for (q = eofmark + 1 ; *q && *p == *q ; p++, q++); |
if (*p == '\n' && *q == '\0') { |
c = PEOF; |
plinno++; |
needprompt = doprompt; |
} else { |
pushstring(line, strlen(line), NULL); |
} |
} |
} |
} |
goto checkend_return; |
} |
/* |
* Parse a redirection operator. The variable "out" points to a string |
* specifying the fd to be redirected. The variable "c" contains the |
* first character of the redirection operator. |
*/ |
parseredir: { |
char fd = *out; |
union node *np; |
np = (union node *)stalloc(sizeof (struct nfile)); |
if (c == '>') { |
np->nfile.fd = 1; |
c = pgetc(); |
if (c == '>') |
np->type = NAPPEND; |
else if (c == '&') |
np->type = NTOFD; |
else if (c == '|') |
np->type = NTOOV; |
else { |
np->type = NTO; |
pungetc(); |
} |
} else { /* c == '<' */ |
np->nfile.fd = 0; |
switch (c = pgetc()) { |
case '<': |
if (sizeof (struct nfile) != sizeof (struct nhere)) { |
np = (union node *)stalloc(sizeof (struct nhere)); |
np->nfile.fd = 0; |
} |
np->type = NHERE; |
heredoc = (struct heredoc *)stalloc(sizeof (struct heredoc)); |
heredoc->here = np; |
if ((c = pgetc()) == '-') { |
heredoc->striptabs = 1; |
} else { |
heredoc->striptabs = 0; |
pungetc(); |
} |
break; |
case '&': |
np->type = NFROMFD; |
break; |
case '>': |
np->type = NFROMTO; |
break; |
default: |
np->type = NFROM; |
pungetc(); |
break; |
} |
} |
if (fd != '\0') |
np->nfile.fd = digit_val(fd); |
redirnode = np; |
goto parseredir_return; |
} |
/* |
* Parse a substitution. At this point, we have read the dollar sign |
* and nothing else. |
*/ |
parsesub: { |
int subtype; |
int typeloc; |
int flags; |
char *p; |
static const char types[] = "}-+?="; |
c = pgetc(); |
if (c != '(' && c != '{' && !is_name(c) && !is_special(c)) { |
USTPUTC('$', out); |
pungetc(); |
} else if (c == '(') { /* $(command) or $((arith)) */ |
if (pgetc() == '(') { |
PARSEARITH(); |
} else { |
pungetc(); |
PARSEBACKQNEW(); |
} |
} else { |
USTPUTC(CTLVAR, out); |
typeloc = out - stackblock(); |
USTPUTC(VSNORMAL, out); |
subtype = VSNORMAL; |
if (c == '{') { |
c = pgetc(); |
if (c == '#') { |
if ((c = pgetc()) == '}') |
c = '#'; |
else |
subtype = VSLENGTH; |
} |
else |
subtype = 0; |
} |
if (is_name(c)) { |
do { |
STPUTC(c, out); |
c = pgetc(); |
} while (is_in_name(c)); |
} else if (is_digit(c)) { |
do { |
USTPUTC(c, out); |
c = pgetc(); |
} while (is_digit(c)); |
} |
else if (is_special(c)) { |
USTPUTC(c, out); |
c = pgetc(); |
} |
else |
badsub: synerror("Bad substitution"); |
STPUTC('=', out); |
flags = 0; |
if (subtype == 0) { |
switch (c) { |
case ':': |
flags = VSNUL; |
c = pgetc(); |
/*FALLTHROUGH*/ |
default: |
p = strchr(types, c); |
if (p == NULL) |
goto badsub; |
subtype = p - types + VSNORMAL; |
break; |
case '%': |
case '#': |
{ |
int cc = c; |
subtype = c == '#' ? VSTRIMLEFT : |
VSTRIMRIGHT; |
c = pgetc(); |
if (c == cc) |
subtype++; |
else |
pungetc(); |
break; |
} |
} |
} else { |
pungetc(); |
} |
if (dblquote || arinest) |
flags |= VSQUOTE; |
*(stackblock() + typeloc) = subtype | flags; |
if (subtype != VSNORMAL) { |
varnest++; |
if (dblquote) { |
dqvarnest++; |
} |
} |
} |
goto parsesub_return; |
} |
/* |
* Called to parse command substitutions. Newstyle is set if the command |
* is enclosed inside $(...); nlpp is a pointer to the head of the linked |
* list of commands (passed by reference), and savelen is the number of |
* characters on the top of the stack which must be preserved. |
*/ |
parsebackq: { |
struct nodelist **nlpp; |
int savepbq; |
union node *n; |
char *volatile str; |
struct jmploc jmploc; |
struct jmploc *volatile savehandler; |
int savelen; |
int saveprompt; |
#ifdef __GNUC__ |
(void) &saveprompt; |
#endif |
savepbq = parsebackquote; |
if (setjmp(jmploc.loc)) { |
if (str) |
ckfree(str); |
parsebackquote = 0; |
handler = savehandler; |
longjmp(handler->loc, 1); |
} |
INTOFF; |
str = NULL; |
savelen = out - stackblock(); |
if (savelen > 0) { |
str = ckmalloc(savelen); |
memcpy(str, stackblock(), savelen); |
} |
savehandler = handler; |
handler = &jmploc; |
INTON; |
if (oldstyle) { |
/* We must read until the closing backquote, giving special |
treatment to some slashes, and then push the string and |
reread it as input, interpreting it normally. */ |
char *pout; |
int pc; |
int psavelen; |
char *pstr; |
STARTSTACKSTR(pout); |
for (;;) { |
if (needprompt) { |
setprompt(2); |
needprompt = 0; |
} |
switch (pc = pgetc()) { |
case '`': |
goto done; |
case '\\': |
if ((pc = pgetc()) == '\n') { |
plinno++; |
if (doprompt) |
setprompt(2); |
else |
setprompt(0); |
/* |
* If eating a newline, avoid putting |
* the newline into the new character |
* stream (via the STPUTC after the |
* switch). |
*/ |
continue; |
} |
if (pc != '\\' && pc != '`' && pc != '$' |
&& (!dblquote || pc != '"')) |
STPUTC('\\', pout); |
break; |
case '\n': |
plinno++; |
needprompt = doprompt; |
break; |
case PEOF: |
startlinno = plinno; |
synerror("EOF in backquote substitution"); |
break; |
default: |
break; |
} |
STPUTC(pc, pout); |
} |
done: |
STPUTC('\0', pout); |
psavelen = pout - stackblock(); |
if (psavelen > 0) { |
pstr = grabstackstr(pout); |
setinputstring(pstr, 1); |
} |
} |
nlpp = &bqlist; |
while (*nlpp) |
nlpp = &(*nlpp)->next; |
*nlpp = (struct nodelist *)stalloc(sizeof (struct nodelist)); |
(*nlpp)->next = NULL; |
parsebackquote = oldstyle; |
if (oldstyle) { |
saveprompt = doprompt; |
doprompt = 0; |
} |
n = list(0); |
if (oldstyle) |
doprompt = saveprompt; |
else { |
if (readtoken() != TRP) |
synexpect(TRP); |
} |
(*nlpp)->n = n; |
if (oldstyle) { |
/* |
* Start reading from old file again, ignoring any pushed back |
* tokens left from the backquote parsing |
*/ |
popfile(); |
tokpushback = 0; |
} |
while (stackblocksize() <= savelen) |
growstackblock(); |
STARTSTACKSTR(out); |
if (str) { |
memcpy(out, str, savelen); |
STADJUST(savelen, out); |
INTOFF; |
ckfree(str); |
str = NULL; |
INTON; |
} |
parsebackquote = savepbq; |
handler = savehandler; |
if (arinest || dblquote) |
USTPUTC(CTLBACKQ | CTLQUOTE, out); |
else |
USTPUTC(CTLBACKQ, out); |
if (oldstyle) |
goto parsebackq_oldreturn; |
else |
goto parsebackq_newreturn; |
} |
/* |
* Parse an arithmetic expansion (indicate start of one and set state) |
*/ |
parsearith: { |
if (++arinest == 1) { |
prevsyntax = syntax; |
syntax = ARISYNTAX; |
USTPUTC(CTLARI, out); |
if (dblquote) |
USTPUTC('"',out); |
else |
USTPUTC(' ',out); |
} else { |
/* |
* we collapse embedded arithmetic expansion to |
* parenthesis, which should be equivalent |
*/ |
USTPUTC('(', out); |
} |
goto parsearith_return; |
} |
} /* end of readtoken */ |
#ifdef mkinit |
RESET { |
tokpushback = 0; |
checkkwd = 0; |
} |
#endif |
/* |
* Returns true if the text contains nothing to expand (no dollar signs |
* or backquotes). |
*/ |
STATIC int |
noexpand(text) |
char *text; |
{ |
char *p; |
char c; |
p = text; |
while ((c = *p++) != '\0') { |
if (c == CTLQUOTEMARK) |
continue; |
if (c == CTLESC) |
p++; |
else if (BASESYNTAX[(int)c] == CCTL) |
return 0; |
} |
return 1; |
} |
/* |
* Return true if the argument is a legal variable name (a letter or |
* underscore followed by zero or more letters, underscores, and digits). |
*/ |
int |
goodname(char *name) |
{ |
char *p; |
p = name; |
if (! is_name(*p)) |
return 0; |
while (*++p) { |
if (! is_in_name(*p)) |
return 0; |
} |
return 1; |
} |
/* |
* Called when an unexpected token is read during the parse. The argument |
* is the token that is expected, or -1 if more than one type of token can |
* occur at this point. |
*/ |
STATIC void |
synexpect(token) |
int token; |
{ |
char msg[64]; |
if (token >= 0) { |
fmtstr(msg, 64, "%s unexpected (expecting %s)", |
tokname[lasttoken], tokname[token]); |
} else { |
fmtstr(msg, 64, "%s unexpected", tokname[lasttoken]); |
} |
synerror(msg); |
/* NOTREACHED */ |
} |
STATIC void |
synerror(msg) |
const char *msg; |
{ |
if (commandname) |
outfmt(&errout, "%s: %d: ", commandname, startlinno); |
outfmt(&errout, "Syntax error: %s\n", msg); |
error((char *)NULL); |
/* NOTREACHED */ |
} |
STATIC void |
setprompt(which) |
int which; |
{ |
whichprompt = which; |
#ifndef SMALL |
if (!el) |
#endif |
out2str(getprompt(NULL)); |
} |
/* |
* called by editline -- any expansions to the prompt |
* should be added here. |
*/ |
const char * |
getprompt(void *unused) |
{ |
switch (whichprompt) { |
case 0: |
return ""; |
case 1: |
return ps1val(); |
case 2: |
return ps2val(); |
default: |
return "<internal prompt error>"; |
} |
} |
/branches/dd/uspace/app/ash/jobs.c |
---|
0,0 → 1,1263 |
/* $NetBSD: jobs.c,v 1.36 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)jobs.c 8.5 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: jobs.c,v 1.36 2000/05/22 10:18:47 elric Exp $"); |
#endif |
#endif /* not lint */ |
#include <fcntl.h> |
#include <signal.h> |
#include <errno.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <paths.h> |
#include <sys/types.h> |
#include <sys/param.h> |
#ifdef BSD |
#include <sys/wait.h> |
#include <sys/time.h> |
#include <sys/resource.h> |
#endif |
#include <sys/ioctl.h> |
#include "shell.h" |
#if JOBS |
#if OLD_TTY_DRIVER |
#include "sgtty.h" |
#else |
#include <termios.h> |
#endif |
#undef CEOF /* syntax.h redefines this */ |
#endif |
#include "redir.h" |
#include "show.h" |
#include "main.h" |
#include "parser.h" |
#include "nodes.h" |
#include "jobs.h" |
#include "options.h" |
#include "trap.h" |
#include "syntax.h" |
#include "input.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "mystring.h" |
struct job *jobtab; /* array of jobs */ |
int njobs; /* size of array */ |
MKINIT short backgndpid = -1; /* pid of last background process */ |
#if JOBS |
int initialpgrp; /* pgrp of shell on invocation */ |
short curjob; /* current job */ |
#endif |
STATIC int intreceived; |
STATIC void restartjob (struct job *); |
STATIC void freejob (struct job *); |
STATIC struct job *getjob (char *); |
STATIC int dowait (int, struct job *); |
STATIC int onsigchild (void); |
STATIC int waitproc (int, int *); |
STATIC void cmdtxt (union node *); |
STATIC void cmdputs (const char *); |
STATIC void waitonint(int); |
#if JOBS |
/* |
* Turn job control on and off. |
* |
* Note: This code assumes that the third arg to ioctl is a character |
* pointer, which is true on Berkeley systems but not System V. Since |
* System V doesn't have job control yet, this isn't a problem now. |
*/ |
MKINIT int jobctl; |
void |
setjobctl(on) |
int on; |
{ |
#ifdef OLD_TTY_DRIVER |
int ldisc; |
#endif |
if (on == jobctl || rootshell == 0) |
return; |
if (on) { |
do { /* while we are in the background */ |
#ifdef OLD_TTY_DRIVER |
if (ioctl(fd2, TIOCGPGRP, (char *)&initialpgrp) < 0) { |
#else |
initialpgrp = tcgetpgrp(fd2); |
if (initialpgrp < 0) { |
#endif |
out2str("sh: can't access tty; job control turned off\n"); |
mflag = 0; |
return; |
} |
if (initialpgrp == -1) |
initialpgrp = getpgrp(); |
else if (initialpgrp != getpgrp()) { |
killpg(initialpgrp, SIGTTIN); |
continue; |
} |
} while (0); |
#ifdef OLD_TTY_DRIVER |
if (ioctl(fd2, TIOCGETD, (char *)&ldisc) < 0 || ldisc != NTTYDISC) { |
out2str("sh: need new tty driver to run job control; job control turned off\n"); |
mflag = 0; |
return; |
} |
#endif |
setsignal(SIGTSTP); |
setsignal(SIGTTOU); |
setsignal(SIGTTIN); |
setpgid(0, rootpid); |
#ifdef OLD_TTY_DRIVER |
ioctl(fd2, TIOCSPGRP, (char *)&rootpid); |
#else |
tcsetpgrp(fd2, rootpid); |
#endif |
} else { /* turning job control off */ |
setpgid(0, initialpgrp); |
#ifdef OLD_TTY_DRIVER |
ioctl(fd2, TIOCSPGRP, (char *)&initialpgrp); |
#else |
tcsetpgrp(fd2, initialpgrp); |
#endif |
setsignal(SIGTSTP); |
setsignal(SIGTTOU); |
setsignal(SIGTTIN); |
} |
jobctl = on; |
} |
#endif |
#ifdef mkinit |
INCLUDE <stdlib.h> |
SHELLPROC { |
backgndpid = -1; |
#if JOBS |
jobctl = 0; |
#endif |
} |
#endif |
#if JOBS |
int |
killcmd(argc, argv) |
int argc; |
char **argv; |
{ |
extern char *signal_names[]; |
int signo = -1; |
int list = 0; |
int i; |
pid_t pid; |
struct job *jp; |
if (argc <= 1) { |
error( |
"Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" |
"kill -l [exitstatus]" |
); |
} |
if (*argv[1] == '-') { |
signo = decode_signal(argv[1]+1); |
if (signo < 0) { |
int c; |
while ((c = nextopt("ls:")) != '\0') |
switch (c) { |
case 'l': |
list = 1; |
break; |
case 's': |
signo = decode_signal(optarg); |
break; |
default: |
error( |
"nextopt returned character code 0%o", c); |
} |
} else |
argptr++; |
} |
if (!list && signo < 0) |
signo = SIGTERM; |
if ((signo < 0 || !*argptr) ^ list) { |
error( |
"Usage: kill [-s sigspec | -signum | -sigspec] [pid | job]... or\n" |
"kill -l [exitstatus]" |
); |
} |
if (list) { |
if (!*argptr) { |
out1fmt("0\n"); |
for (i = 1; i < NSIG; i++) { |
if (strncmp(signal_names[i], "SIGJUNK(", 8) |
== 0) |
continue; |
out1fmt("%s\n", signal_names[i] + 3); |
} |
return 0; |
} |
signo = atoi(*argptr); |
if (signo > 128) |
signo -= 128; |
if (0 < signo && signo < NSIG) |
out1fmt("%s\n", signal_names[signo] + 3); |
else |
error("invalid signal number or exit status: %s", |
*argptr); |
return 0; |
} |
do { |
if (**argptr == '%') { |
jp = getjob(*argptr); |
if (jp->jobctl == 0) |
error("job %s not created under job control", |
*argptr); |
pid = -jp->ps[0].pid; |
} else |
pid = atoi(*argptr); |
if (kill(pid, signo) != 0) |
error("%s: %s", *argptr, strerror(errno)); |
} while (*++argptr); |
return 0; |
} |
int |
fgcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct job *jp; |
int pgrp; |
int status; |
jp = getjob(argv[1]); |
if (jp->jobctl == 0) |
error("job not created under job control"); |
pgrp = jp->ps[0].pid; |
#ifdef OLD_TTY_DRIVER |
ioctl(fd2, TIOCSPGRP, (char *)&pgrp); |
#else |
tcsetpgrp(fd2, pgrp); |
#endif |
restartjob(jp); |
INTOFF; |
status = waitforjob(jp); |
INTON; |
return status; |
} |
int |
bgcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct job *jp; |
do { |
jp = getjob(*++argv); |
if (jp->jobctl == 0) |
error("job not created under job control"); |
restartjob(jp); |
} while (--argc > 1); |
return 0; |
} |
STATIC void |
restartjob(jp) |
struct job *jp; |
{ |
struct procstat *ps; |
int i; |
if (jp->state == JOBDONE) |
return; |
INTOFF; |
killpg(jp->ps[0].pid, SIGCONT); |
for (ps = jp->ps, i = jp->nprocs ; --i >= 0 ; ps++) { |
if (WIFSTOPPED(ps->status)) { |
ps->status = -1; |
jp->state = 0; |
} |
} |
INTON; |
} |
#endif |
int |
jobscmd(argc, argv) |
int argc; |
char **argv; |
{ |
showjobs(0); |
return 0; |
} |
/* |
* Print a list of jobs. If "change" is nonzero, only print jobs whose |
* statuses have changed since the last call to showjobs. |
* |
* If the shell is interrupted in the process of creating a job, the |
* result may be a job structure containing zero processes. Such structures |
* will be freed here. |
*/ |
void |
showjobs(change) |
int change; |
{ |
int jobno; |
int procno; |
int i; |
struct job *jp; |
struct procstat *ps; |
int col; |
char s[64]; |
TRACE(("showjobs(%d) called\n", change)); |
while (dowait(0, (struct job *)NULL) > 0); |
for (jobno = 1, jp = jobtab ; jobno <= njobs ; jobno++, jp++) { |
if (! jp->used) |
continue; |
if (jp->nprocs == 0) { |
freejob(jp); |
continue; |
} |
if (change && ! jp->changed) |
continue; |
procno = jp->nprocs; |
for (ps = jp->ps ; ; ps++) { /* for each process */ |
if (ps == jp->ps) |
fmtstr(s, 64, "[%d] %ld ", jobno, |
(long)ps->pid); |
else |
fmtstr(s, 64, " %ld ", |
(long)ps->pid); |
out1str(s); |
col = strlen(s); |
s[0] = '\0'; |
if (ps->status == -1) { |
/* don't print anything */ |
} else if (WIFEXITED(ps->status)) { |
fmtstr(s, 64, "Exit %d", |
WEXITSTATUS(ps->status)); |
} else { |
#if JOBS |
if (WIFSTOPPED(ps->status)) |
i = WSTOPSIG(ps->status); |
else /* WIFSIGNALED(ps->status) */ |
#endif |
i = WTERMSIG(ps->status); |
if ((i & 0x7F) < NSIG && sys_siglist[i & 0x7F]) |
scopy(sys_siglist[i & 0x7F], s); |
else |
fmtstr(s, 64, "Signal %d", i & 0x7F); |
if (WCOREDUMP(ps->status)) |
strcat(s, " (core dumped)"); |
} |
out1str(s); |
col += strlen(s); |
do { |
out1c(' '); |
col++; |
} while (col < 30); |
out1str(ps->cmd); |
out1c('\n'); |
if (--procno <= 0) |
break; |
} |
jp->changed = 0; |
if (jp->state == JOBDONE) { |
freejob(jp); |
} |
} |
} |
/* |
* Mark a job structure as unused. |
*/ |
STATIC void |
freejob(jp) |
struct job *jp; |
{ |
struct procstat *ps; |
int i; |
INTOFF; |
for (i = jp->nprocs, ps = jp->ps ; --i >= 0 ; ps++) { |
if (ps->cmd != nullstr) |
ckfree(ps->cmd); |
} |
if (jp->ps != &jp->ps0) |
ckfree(jp->ps); |
jp->used = 0; |
#if JOBS |
if (curjob == jp - jobtab + 1) |
curjob = 0; |
#endif |
INTON; |
} |
int |
waitcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct job *job; |
int status, retval; |
struct job *jp; |
if (argc > 1) { |
job = getjob(argv[1]); |
} else { |
job = NULL; |
} |
for (;;) { /* loop until process terminated or stopped */ |
if (job != NULL) { |
if (job->state) { |
status = job->ps[job->nprocs - 1].status; |
if (WIFEXITED(status)) |
retval = WEXITSTATUS(status); |
#if JOBS |
else if (WIFSTOPPED(status)) |
retval = WSTOPSIG(status) + 128; |
#endif |
else { |
/* XXX: limits number of signals */ |
retval = WTERMSIG(status) + 128; |
} |
if (! iflag) |
freejob(job); |
return retval; |
} |
} else { |
for (jp = jobtab ; ; jp++) { |
if (jp >= jobtab + njobs) { /* no running procs */ |
return 0; |
} |
if (jp->used && jp->state == 0) |
break; |
} |
} |
dowait(1, (struct job *)NULL); |
} |
} |
int |
jobidcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct job *jp; |
int i; |
jp = getjob(argv[1]); |
for (i = 0 ; i < jp->nprocs ; ) { |
out1fmt("%ld", (long)jp->ps[i].pid); |
out1c(++i < jp->nprocs? ' ' : '\n'); |
} |
return 0; |
} |
/* |
* Convert a job name to a job structure. |
*/ |
STATIC struct job * |
getjob(name) |
char *name; |
{ |
int jobno; |
struct job *jp; |
int pid; |
int i; |
if (name == NULL) { |
#if JOBS |
currentjob: |
if ((jobno = curjob) == 0 || jobtab[jobno - 1].used == 0) |
error("No current job"); |
return &jobtab[jobno - 1]; |
#else |
error("No current job"); |
#endif |
} else if (name[0] == '%') { |
if (is_digit(name[1])) { |
jobno = number(name + 1); |
if (jobno > 0 && jobno <= njobs |
&& jobtab[jobno - 1].used != 0) |
return &jobtab[jobno - 1]; |
#if JOBS |
} else if (name[1] == '%' && name[2] == '\0') { |
goto currentjob; |
#endif |
} else { |
struct job *found = NULL; |
for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { |
if (jp->used && jp->nprocs > 0 |
&& prefix(name + 1, jp->ps[0].cmd)) { |
if (found) |
error("%s: ambiguous", name); |
found = jp; |
} |
} |
if (found) |
return found; |
} |
} else if (is_number(name)) { |
pid = number(name); |
for (jp = jobtab, i = njobs ; --i >= 0 ; jp++) { |
if (jp->used && jp->nprocs > 0 |
&& jp->ps[jp->nprocs - 1].pid == pid) |
return jp; |
} |
} |
error("No such job: %s", name); |
/* NOTREACHED */ |
} |
/* |
* Return a new job structure, |
*/ |
struct job * |
makejob(node, nprocs) |
union node *node; |
int nprocs; |
{ |
int i; |
struct job *jp; |
for (i = njobs, jp = jobtab ; ; jp++) { |
if (--i < 0) { |
INTOFF; |
if (njobs == 0) { |
jobtab = ckmalloc(4 * sizeof jobtab[0]); |
} else { |
jp = ckmalloc((njobs + 4) * sizeof jobtab[0]); |
memcpy(jp, jobtab, njobs * sizeof jp[0]); |
/* Relocate `ps' pointers */ |
for (i = 0; i < njobs; i++) |
if (jp[i].ps == &jobtab[i].ps0) |
jp[i].ps = &jp[i].ps0; |
ckfree(jobtab); |
jobtab = jp; |
} |
jp = jobtab + njobs; |
for (i = 4 ; --i >= 0 ; jobtab[njobs++].used = 0); |
INTON; |
break; |
} |
if (jp->used == 0) |
break; |
} |
INTOFF; |
jp->state = 0; |
jp->used = 1; |
jp->changed = 0; |
jp->nprocs = 0; |
#if JOBS |
jp->jobctl = jobctl; |
#endif |
if (nprocs > 1) { |
jp->ps = ckmalloc(nprocs * sizeof (struct procstat)); |
} else { |
jp->ps = &jp->ps0; |
} |
INTON; |
TRACE(("makejob(0x%lx, %d) returns %%%d\n", (long)node, nprocs, |
jp - jobtab + 1)); |
return jp; |
} |
/* |
* Fork of a subshell. If we are doing job control, give the subshell its |
* own process group. Jp is a job structure that the job is to be added to. |
* N is the command that will be evaluated by the child. Both jp and n may |
* be NULL. The mode parameter can be one of the following: |
* FORK_FG - Fork off a foreground process. |
* FORK_BG - Fork off a background process. |
* FORK_NOJOB - Like FORK_FG, but don't give the process its own |
* process group even if job control is on. |
* |
* When job control is turned off, background processes have their standard |
* input redirected to /dev/null (except for the second and later processes |
* in a pipeline). |
*/ |
int |
forkshell(jp, n, mode) |
union node *n; |
struct job *jp; |
int mode; |
{ |
int pid; |
int pgrp; |
const char *devnull = _PATH_DEVNULL; |
const char *nullerr = "Can't open %s"; |
TRACE(("forkshell(%%%d, 0x%lx, %d) called\n", jp - jobtab, (long)n, |
mode)); |
INTOFF; |
pid = fork(); |
if (pid == -1) { |
TRACE(("Fork failed, errno=%d\n", errno)); |
INTON; |
error("Cannot fork"); |
} |
if (pid == 0) { |
struct job *p; |
int wasroot; |
int i; |
TRACE(("Child shell %d\n", getpid())); |
wasroot = rootshell; |
rootshell = 0; |
closescript(); |
INTON; |
clear_traps(); |
#if JOBS |
jobctl = 0; /* do job control only in root shell */ |
if (wasroot && mode != FORK_NOJOB && mflag) { |
if (jp == NULL || jp->nprocs == 0) |
pgrp = getpid(); |
else |
pgrp = jp->ps[0].pid; |
setpgid(0, pgrp); |
if (mode == FORK_FG) { |
/*** this causes superfluous TIOCSPGRPS ***/ |
#ifdef OLD_TTY_DRIVER |
if (ioctl(fd2, TIOCSPGRP, (char *)&pgrp) < 0) |
error("TIOCSPGRP failed, errno=%d", errno); |
#else |
if (tcsetpgrp(fd2, pgrp) < 0) |
error("tcsetpgrp failed, errno=%d", errno); |
#endif |
} |
setsignal(SIGTSTP); |
setsignal(SIGTTOU); |
} else if (mode == FORK_BG) { |
ignoresig(SIGINT); |
ignoresig(SIGQUIT); |
ignoresig(SIGHUP); |
if ((jp == NULL || jp->nprocs == 0) && |
! fd0_redirected_p ()) { |
close(0); |
if (open(devnull, O_RDONLY) != 0) |
error(nullerr, devnull); |
} |
} |
#else |
if (mode == FORK_BG) { |
ignoresig(SIGINT); |
ignoresig(SIGQUIT); |
ignoresig(SIGHUP); |
if ((jp == NULL || jp->nprocs == 0) && |
! fd0_redirected_p ()) { |
close(0); |
if (open(devnull, O_RDONLY) != 0) |
error(nullerr, devnull); |
} |
} |
#endif |
for (i = njobs, p = jobtab ; --i >= 0 ; p++) |
if (p->used) |
freejob(p); |
if (wasroot && iflag) { |
setsignal(SIGINT); |
setsignal(SIGQUIT); |
setsignal(SIGTERM); |
} |
return pid; |
} |
if (rootshell && mode != FORK_NOJOB && mflag) { |
if (jp == NULL || jp->nprocs == 0) |
pgrp = pid; |
else |
pgrp = jp->ps[0].pid; |
setpgid(pid, pgrp); |
} |
if (mode == FORK_BG) |
backgndpid = pid; /* set $! */ |
if (jp) { |
struct procstat *ps = &jp->ps[jp->nprocs++]; |
ps->pid = pid; |
ps->status = -1; |
ps->cmd = nullstr; |
if (iflag && rootshell && n) |
ps->cmd = commandtext(n); |
} |
INTON; |
TRACE(("In parent shell: child = %d\n", pid)); |
return pid; |
} |
/* |
* Wait for job to finish. |
* |
* Under job control we have the problem that while a child process is |
* running interrupts generated by the user are sent to the child but not |
* to the shell. This means that an infinite loop started by an inter- |
* active user may be hard to kill. With job control turned off, an |
* interactive user may place an interactive program inside a loop. If |
* the interactive program catches interrupts, the user doesn't want |
* these interrupts to also abort the loop. The approach we take here |
* is to have the shell ignore interrupt signals while waiting for a |
* forground process to terminate, and then send itself an interrupt |
* signal if the child process was terminated by an interrupt signal. |
* Unfortunately, some programs want to do a bit of cleanup and then |
* exit on interrupt; unless these processes terminate themselves by |
* sending a signal to themselves (instead of calling exit) they will |
* confuse this approach. |
*/ |
int |
waitforjob(jp) |
struct job *jp; |
{ |
#if JOBS |
int mypgrp = getpgrp(); |
#endif |
int status; |
int st; |
struct sigaction act, oact; |
INTOFF; |
intreceived = 0; |
#if JOBS |
if (!jobctl) { |
#else |
if (!iflag) { |
#endif |
sigaction(SIGINT, 0, &act); |
act.sa_handler = waitonint; |
sigaction(SIGINT, &act, &oact); |
} |
TRACE(("waitforjob(%%%d) called\n", jp - jobtab + 1)); |
while (jp->state == 0) { |
dowait(1, jp); |
} |
#if JOBS |
if (!jobctl) { |
#else |
if (!iflag) { |
#endif |
extern char *trap[]; |
sigaction(SIGINT, &oact, 0); |
if (intreceived && trap[SIGINT]) kill(getpid(), SIGINT); |
} |
#if JOBS |
if (jp->jobctl) { |
#ifdef OLD_TTY_DRIVER |
if (ioctl(fd2, TIOCSPGRP, (char *)&mypgrp) < 0) |
error("TIOCSPGRP failed, errno=%d\n", errno); |
#else |
if (tcsetpgrp(fd2, mypgrp) < 0) |
error("tcsetpgrp failed, errno=%d\n", errno); |
#endif |
} |
if (jp->state == JOBSTOPPED) |
curjob = jp - jobtab + 1; |
#endif |
status = jp->ps[jp->nprocs - 1].status; |
/* convert to 8 bits */ |
if (WIFEXITED(status)) |
st = WEXITSTATUS(status); |
#if JOBS |
else if (WIFSTOPPED(status)) |
st = WSTOPSIG(status) + 128; |
#endif |
else |
st = WTERMSIG(status) + 128; |
#if JOBS |
if (jp->jobctl) { |
/* |
* This is truly gross. |
* If we're doing job control, then we did a TIOCSPGRP which |
* caused us (the shell) to no longer be in the controlling |
* session -- so we wouldn't have seen any ^C/SIGINT. So, we |
* intuit from the subprocess exit status whether a SIGINT |
* occured, and if so interrupt ourselves. Yuck. - mycroft |
*/ |
if (WIFSIGNALED(status) && WTERMSIG(status) == SIGINT) |
raise(SIGINT); |
} |
#endif |
if (! JOBS || jp->state == JOBDONE) |
freejob(jp); |
INTON; |
return st; |
} |
/* |
* Wait for a process to terminate. |
*/ |
STATIC int |
dowait(block, job) |
int block; |
struct job *job; |
{ |
int pid; |
int status; |
struct procstat *sp; |
struct job *jp; |
struct job *thisjob; |
int done; |
int stopped; |
int core; |
int sig; |
TRACE(("dowait(%d) called\n", block)); |
do { |
pid = waitproc(block, &status); |
TRACE(("wait returns %d, status=%d\n", pid, status)); |
} while (pid == -1 && errno == EINTR); |
if (pid <= 0) |
return pid; |
INTOFF; |
thisjob = NULL; |
for (jp = jobtab ; jp < jobtab + njobs ; jp++) { |
if (jp->used) { |
done = 1; |
stopped = 1; |
for (sp = jp->ps ; sp < jp->ps + jp->nprocs ; sp++) { |
if (sp->pid == -1) |
continue; |
if (sp->pid == pid) { |
TRACE(("Changing status of proc %d from 0x%x to 0x%x\n", pid, sp->status, status)); |
sp->status = status; |
thisjob = jp; |
} |
if (sp->status == -1) |
stopped = 0; |
else if (WIFSTOPPED(sp->status)) |
done = 0; |
} |
if (stopped) { /* stopped or done */ |
int state = done? JOBDONE : JOBSTOPPED; |
if (jp->state != state) { |
TRACE(("Job %d: changing state from %d to %d\n", jp - jobtab + 1, jp->state, state)); |
jp->state = state; |
#if JOBS |
if (done && curjob == jp - jobtab + 1) |
curjob = 0; /* no current job */ |
#endif |
} |
} |
} |
} |
INTON; |
if (! rootshell || ! iflag || (job && thisjob == job)) { |
core = WCOREDUMP(status); |
#if JOBS |
if (WIFSTOPPED(status)) sig = WSTOPSIG(status); |
else |
#endif |
if (WIFEXITED(status)) sig = 0; |
else sig = WTERMSIG(status); |
if (sig != 0 && sig != SIGINT && sig != SIGPIPE) { |
if (thisjob != job) |
outfmt(out2, "%d: ", pid); |
#if JOBS |
if (sig == SIGTSTP && rootshell && iflag) |
outfmt(out2, "%%%ld ", |
(long)(job - jobtab + 1)); |
#endif |
if (sig < NSIG && sys_siglist[sig]) |
out2str(sys_siglist[sig]); |
else |
outfmt(out2, "Signal %d", sig); |
if (core) |
out2str(" - core dumped"); |
out2c('\n'); |
flushout(&errout); |
} else { |
TRACE(("Not printing status: status=%d, sig=%d\n", |
status, sig)); |
} |
} else { |
TRACE(("Not printing status, rootshell=%d, job=0x%x\n", rootshell, job)); |
if (thisjob) |
thisjob->changed = 1; |
} |
return pid; |
} |
/* |
* Do a wait system call. If job control is compiled in, we accept |
* stopped processes. If block is zero, we return a value of zero |
* rather than blocking. |
* |
* System V doesn't have a non-blocking wait system call. It does |
* have a SIGCLD signal that is sent to a process when one of it's |
* children dies. The obvious way to use SIGCLD would be to install |
* a handler for SIGCLD which simply bumped a counter when a SIGCLD |
* was received, and have waitproc bump another counter when it got |
* the status of a process. Waitproc would then know that a wait |
* system call would not block if the two counters were different. |
* This approach doesn't work because if a process has children that |
* have not been waited for, System V will send it a SIGCLD when it |
* installs a signal handler for SIGCLD. What this means is that when |
* a child exits, the shell will be sent SIGCLD signals continuously |
* until is runs out of stack space, unless it does a wait call before |
* restoring the signal handler. The code below takes advantage of |
* this (mis)feature by installing a signal handler for SIGCLD and |
* then checking to see whether it was called. If there are any |
* children to be waited for, it will be. |
* |
* If neither SYSV nor BSD is defined, we don't implement nonblocking |
* waits at all. In this case, the user will not be informed when |
* a background process until the next time she runs a real program |
* (as opposed to running a builtin command or just typing return), |
* and the jobs command may give out of date information. |
*/ |
#ifdef SYSV |
STATIC int gotsigchild; |
STATIC int onsigchild() { |
gotsigchild = 1; |
} |
#endif |
STATIC int |
waitproc(block, status) |
int block; |
int *status; |
{ |
#ifdef BSD |
int flags; |
flags = 0; |
#if JOBS |
if (jobctl) |
flags |= WUNTRACED; |
#endif |
if (block == 0) |
flags |= WNOHANG; |
return wait3(status, flags, (struct rusage *)NULL); |
#else |
#ifdef SYSV |
int (*save)(); |
if (block == 0) { |
gotsigchild = 0; |
save = signal(SIGCLD, onsigchild); |
signal(SIGCLD, save); |
if (gotsigchild == 0) |
return 0; |
} |
return wait(status); |
#else |
if (block == 0) |
return 0; |
return wait(status); |
#endif |
#endif |
} |
/* |
* return 1 if there are stopped jobs, otherwise 0 |
*/ |
int job_warning = 0; |
int |
stoppedjobs() |
{ |
int jobno; |
struct job *jp; |
if (job_warning) |
return (0); |
for (jobno = 1, jp = jobtab; jobno <= njobs; jobno++, jp++) { |
if (jp->used == 0) |
continue; |
if (jp->state == JOBSTOPPED) { |
out2str("You have stopped jobs.\n"); |
job_warning = 2; |
return (1); |
} |
} |
return (0); |
} |
/* |
* Return a string identifying a command (to be printed by the |
* jobs command. |
*/ |
STATIC char *cmdnextc; |
STATIC int cmdnleft; |
#define MAXCMDTEXT 200 |
char * |
commandtext(n) |
union node *n; |
{ |
char *name; |
cmdnextc = name = ckmalloc(MAXCMDTEXT); |
cmdnleft = MAXCMDTEXT - 4; |
cmdtxt(n); |
*cmdnextc = '\0'; |
return name; |
} |
STATIC void |
cmdtxt(n) |
union node *n; |
{ |
union node *np; |
struct nodelist *lp; |
const char *p; |
int i; |
char s[2]; |
if (n == NULL) |
return; |
switch (n->type) { |
case NSEMI: |
cmdtxt(n->nbinary.ch1); |
cmdputs("; "); |
cmdtxt(n->nbinary.ch2); |
break; |
case NAND: |
cmdtxt(n->nbinary.ch1); |
cmdputs(" && "); |
cmdtxt(n->nbinary.ch2); |
break; |
case NOR: |
cmdtxt(n->nbinary.ch1); |
cmdputs(" || "); |
cmdtxt(n->nbinary.ch2); |
break; |
case NPIPE: |
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { |
cmdtxt(lp->n); |
if (lp->next) |
cmdputs(" | "); |
} |
break; |
case NSUBSHELL: |
cmdputs("("); |
cmdtxt(n->nredir.n); |
cmdputs(")"); |
break; |
case NREDIR: |
case NBACKGND: |
cmdtxt(n->nredir.n); |
break; |
case NIF: |
cmdputs("if "); |
cmdtxt(n->nif.test); |
cmdputs("; then "); |
cmdtxt(n->nif.ifpart); |
cmdputs("..."); |
break; |
case NWHILE: |
cmdputs("while "); |
goto until; |
case NUNTIL: |
cmdputs("until "); |
until: |
cmdtxt(n->nbinary.ch1); |
cmdputs("; do "); |
cmdtxt(n->nbinary.ch2); |
cmdputs("; done"); |
break; |
case NFOR: |
cmdputs("for "); |
cmdputs(n->nfor.var); |
cmdputs(" in ..."); |
break; |
case NCASE: |
cmdputs("case "); |
cmdputs(n->ncase.expr->narg.text); |
cmdputs(" in ..."); |
break; |
case NDEFUN: |
cmdputs(n->narg.text); |
cmdputs("() ..."); |
break; |
case NCMD: |
for (np = n->ncmd.args ; np ; np = np->narg.next) { |
cmdtxt(np); |
if (np->narg.next) |
cmdputs(" "); |
} |
for (np = n->ncmd.redirect ; np ; np = np->nfile.next) { |
cmdputs(" "); |
cmdtxt(np); |
} |
break; |
case NARG: |
cmdputs(n->narg.text); |
break; |
case NTO: |
p = ">"; i = 1; goto redir; |
case NAPPEND: |
p = ">>"; i = 1; goto redir; |
case NTOFD: |
p = ">&"; i = 1; goto redir; |
case NTOOV: |
p = ">|"; i = 1; goto redir; |
case NFROM: |
p = "<"; i = 0; goto redir; |
case NFROMFD: |
p = "<&"; i = 0; goto redir; |
case NFROMTO: |
p = "<>"; i = 0; goto redir; |
redir: |
if (n->nfile.fd != i) { |
s[0] = n->nfile.fd + '0'; |
s[1] = '\0'; |
cmdputs(s); |
} |
cmdputs(p); |
if (n->type == NTOFD || n->type == NFROMFD) { |
s[0] = n->ndup.dupfd + '0'; |
s[1] = '\0'; |
cmdputs(s); |
} else { |
cmdtxt(n->nfile.fname); |
} |
break; |
case NHERE: |
case NXHERE: |
cmdputs("<<..."); |
break; |
default: |
cmdputs("???"); |
break; |
} |
} |
STATIC void |
cmdputs(s) |
const char *s; |
{ |
const char *p; |
char *q; |
char c; |
int subtype = 0; |
if (cmdnleft <= 0) |
return; |
p = s; |
q = cmdnextc; |
while ((c = *p++) != '\0') { |
if (c == CTLESC) |
*q++ = *p++; |
else if (c == CTLVAR) { |
*q++ = '$'; |
if (--cmdnleft > 0) |
*q++ = '{'; |
subtype = *p++; |
} else if (c == '=' && subtype != 0) { |
*q++ = "}-+?="[(subtype & VSTYPE) - VSNORMAL]; |
subtype = 0; |
} else if (c == CTLENDVAR) { |
*q++ = '}'; |
} else if (c == CTLBACKQ || c == CTLBACKQ+CTLQUOTE) |
cmdnleft++; /* ignore it */ |
else |
*q++ = c; |
if (--cmdnleft <= 0) { |
*q++ = '.'; |
*q++ = '.'; |
*q++ = '.'; |
break; |
} |
} |
cmdnextc = q; |
} |
STATIC void waitonint(int sig) { |
intreceived = 1; |
return; |
} |
/branches/dd/uspace/app/ash/memalloc.h |
---|
0,0 → 1,81 |
/* $NetBSD: memalloc.h,v 1.11 2000/11/01 19:56:01 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)memalloc.h 8.2 (Berkeley) 5/4/95 |
*/ |
struct stackmark { |
struct stack_block *stackp; |
char *stacknxt; |
int stacknleft; |
struct stackmark *marknext; |
}; |
extern char *stacknxt; |
extern int stacknleft; |
extern int sstrnleft; |
extern int herefd; |
pointer ckmalloc (int); |
pointer ckrealloc (pointer, int); |
char *savestr (char *); |
pointer stalloc (int); |
void stunalloc (pointer); |
void setstackmark (struct stackmark *); |
void popstackmark (struct stackmark *); |
void growstackblock (void); |
void grabstackblock (int); |
char *growstackstr (void); |
char *makestrspace (void); |
void ungrabstackstr (char *, char *); |
#define stackblock() stacknxt |
#define stackblocksize() stacknleft |
#define STARTSTACKSTR(p) p = stackblock(), sstrnleft = stackblocksize() |
#define STPUTC(c, p) (--sstrnleft >= 0? (*p++ = (c)) : (p = growstackstr(), *p++ = (c))) |
#define CHECKSTRSPACE(n, p) { if (sstrnleft < n) p = makestrspace(); } |
#define USTPUTC(c, p) (--sstrnleft, *p++ = (c)) |
#define STACKSTRNUL(p) (sstrnleft == 0? (p = growstackstr(), *p = '\0') : (*p = '\0')) |
#define STUNPUTC(p) (++sstrnleft, --p) |
#define STTOPC(p) p[-1] |
#define STADJUST(amount, p) (p += (amount), sstrnleft -= (amount)) |
#define grabstackstr(p) stalloc(stackblocksize() - sstrnleft) |
#define ckfree(p) free((pointer)(p)) |
/branches/dd/uspace/app/ash/alias.h |
---|
0,0 → 1,53 |
/* $NetBSD: alias.h,v 1.4 1995/05/11 21:28:42 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)alias.h 8.2 (Berkeley) 5/4/95 |
*/ |
#define ALIASINUSE 1 |
struct alias { |
struct alias *next; |
char *name; |
char *val; |
int flag; |
}; |
struct alias *lookupalias (char *, int); |
int aliascmd (int, char **); |
int unaliascmd (int, char **); |
void rmaliases (void); |
/branches/dd/uspace/app/ash/output.c |
---|
0,0 → 1,634 |
/* $NetBSD: output.c,v 1.23 2001/01/07 23:39:07 lukem Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)output.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: output.c,v 1.23 2001/01/07 23:39:07 lukem Exp $"); |
#endif |
#endif /* not lint */ |
/* |
* Shell output routines. We use our own output routines because: |
* When a builtin command is interrupted we have to discard |
* any pending output. |
* When a builtin command appears in back quotes, we want to |
* save the output of the command in a region obtained |
* via malloc, rather than doing a fork and reading the |
* output of the command via a pipe. |
* Our output routines may be smaller than the stdio routines. |
*/ |
#include <sys/types.h> /* quad_t */ |
#include <sys/param.h> /* BSD4_4 */ |
#include <sys/ioctl.h> |
#include <stdio.h> /* defines BUFSIZ */ |
#include <string.h> |
#include <errno.h> |
#include <unistd.h> |
#include <stdlib.h> |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
#undef CEOF /* get rid of the redefine warning */ |
#include <fcntl.h> |
#endif |
#include "shell.h" |
#include "syntax.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#define OUTBUFSIZ BUFSIZ |
#define BLOCK_OUT -2 /* output to a fixed block of memory */ |
#define MEM_OUT -3 /* output to dynamically allocated memory */ |
#define OUTPUT_ERR 01 /* error occurred on output */ |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
struct output output = {NULL, NULL, 0, NULL, 0, 1, 0}; |
struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0}; |
struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0}; |
#else |
struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0}; |
struct output errout = {NULL, 0, NULL, 100, 2, 0}; |
struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0}; |
#endif |
struct output *out1 = &output; |
struct output *out2 = &errout; |
#ifdef mkinit |
INCLUDE "output.h" |
INCLUDE "memalloc.h" |
INIT { |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
initstreams(); |
#endif |
} |
RESET { |
out1 = &output; |
out2 = &errout; |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
if (memout.stream != NULL) |
closememout(); |
#endif |
if (memout.buf != NULL) { |
ckfree(memout.buf); |
memout.buf = NULL; |
} |
} |
#endif |
#ifdef notdef /* no longer used */ |
/* |
* Set up an output file to write to memory rather than a file. |
*/ |
void |
open_mem(block, length, file) |
char *block; |
int length; |
struct output *file; |
{ |
file->nextc = block; |
file->nleft = --length; |
file->fd = BLOCK_OUT; |
file->flags = 0; |
} |
#endif |
void |
outstr(p, file) |
const char *p; |
struct output *file; |
{ |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
fputs(p, file->stream); |
#else |
while (*p) |
outc(*p++, file); |
#endif |
if (file == out2) |
flushout(file); |
} |
#if !defined(_GNU_SOURCE) || defined(__UCLIBC__) |
char out_junk[16]; |
void |
emptyoutbuf(dest) |
struct output *dest; |
{ |
int offset; |
if (dest->fd == BLOCK_OUT) { |
dest->nextc = out_junk; |
dest->nleft = sizeof out_junk; |
dest->flags |= OUTPUT_ERR; |
} else if (dest->buf == NULL) { |
INTOFF; |
dest->buf = ckmalloc(dest->bufsize); |
dest->nextc = dest->buf; |
dest->nleft = dest->bufsize; |
INTON; |
} else if (dest->fd == MEM_OUT) { |
offset = dest->bufsize; |
INTOFF; |
dest->bufsize <<= 1; |
dest->buf = ckrealloc(dest->buf, dest->bufsize); |
dest->nleft = dest->bufsize - offset; |
dest->nextc = dest->buf + offset; |
INTON; |
} else { |
flushout(dest); |
} |
dest->nleft--; |
} |
#endif |
void |
flushall() { |
flushout(&output); |
flushout(&errout); |
} |
#if !defined(_GNU_SOURCE) || defined(__UCLIBC__) |
void |
flushout(dest) |
struct output *dest; |
{ |
if (dest->buf == NULL || dest->nextc == dest->buf || dest->fd < 0) |
return; |
if (xwrite(dest->fd, dest->buf, dest->nextc - dest->buf) < 0) |
dest->flags |= OUTPUT_ERR; |
dest->nextc = dest->buf; |
dest->nleft = dest->bufsize; |
} |
#endif |
void |
freestdout() { |
INTOFF; |
if (output.buf) { |
ckfree(output.buf); |
output.buf = NULL; |
output.nleft = 0; |
} |
INTON; |
} |
void |
#ifdef __STDC__ |
outfmt(struct output *file, const char *fmt, ...) |
#else |
void |
outfmt(va_alist) |
va_dcl |
#endif |
{ |
va_list ap; |
#ifndef __STDC__ |
struct output *file; |
const char *fmt; |
va_start(ap); |
file = va_arg(ap, struct output *); |
fmt = va_arg(ap, const char *); |
#else |
va_start(ap, fmt); |
#endif |
doformat(file, fmt, ap); |
va_end(ap); |
} |
void |
#ifdef __STDC__ |
out1fmt(const char *fmt, ...) |
#else |
out1fmt(va_alist) |
va_dcl |
#endif |
{ |
va_list ap; |
#ifndef __STDC__ |
const char *fmt; |
va_start(ap); |
fmt = va_arg(ap, const char *); |
#else |
va_start(ap, fmt); |
#endif |
doformat(out1, fmt, ap); |
va_end(ap); |
} |
#if !defined(__GLIBC__) && !defined(__UCLIBC__) |
void |
#ifdef __STDC__ |
dprintf(const char *fmt, ...) |
#else |
dprintf(va_alist) |
va_dcl |
#endif |
{ |
va_list ap; |
#ifndef __STDC__ |
const char *fmt; |
va_start(ap); |
fmt = va_arg(ap, const char *); |
#else |
va_start(ap, fmt); |
#endif |
doformat(out2, fmt, ap); |
va_end(ap); |
flushout(out2); |
} |
#endif |
void |
#ifdef __STDC__ |
fmtstr(char *outbuf, size_t length, const char *fmt, ...) |
#else |
fmtstr(va_alist) |
va_dcl |
#endif |
{ |
va_list ap; |
#if !defined(_GNU_SOURCE) || defined(__UCLIBC__) |
struct output strout; |
#endif |
#ifndef __STDC__ |
char *outbuf; |
size_t length; |
const char *fmt; |
va_start(ap); |
outbuf = va_arg(ap, char *); |
length = va_arg(ap, size_t); |
fmt = va_arg(ap, const char *); |
#else |
va_start(ap, fmt); |
#endif |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
vsnprintf(outbuf, length, fmt, ap); |
#else |
strout.nextc = outbuf; |
strout.nleft = length; |
strout.fd = BLOCK_OUT; |
strout.flags = 0; |
doformat(&strout, fmt, ap); |
outc('\0', &strout); |
if (strout.flags & OUTPUT_ERR) |
outbuf[length - 1] = '\0'; |
#endif |
} |
#if !defined(_GNU_SOURCE) || defined(__UCLIBC__) |
/* |
* Formatted output. This routine handles a subset of the printf formats: |
* - Formats supported: d, u, o, p, X, s, and c. |
* - The x format is also accepted but is treated like X. |
* - The l, ll and q modifiers are accepted. |
* - The - and # flags are accepted; # only works with the o format. |
* - Width and precision may be specified with any format except c. |
* - An * may be given for the width or precision. |
* - The obsolete practice of preceding the width with a zero to get |
* zero padding is not supported; use the precision field. |
* - A % may be printed by writing %% in the format string. |
*/ |
#define TEMPSIZE 24 |
static const char digit[] = "0123456789ABCDEF"; |
#ifdef BSD4_4 |
#define HAVE_VASPRINTF 1 |
#endif |
void |
doformat(dest, f, ap) |
struct output *dest; |
const char *f; /* format string */ |
va_list ap; |
{ |
#if HAVE_VASPRINTF |
char *s; |
vasprintf(&s, f, ap); |
outstr(s, dest); |
free(s); |
#else /* !HAVE_VASPRINTF */ |
char c; |
char temp[TEMPSIZE]; |
int flushleft; |
int sharp; |
int width; |
int prec; |
int islong; |
int isquad; |
char *p; |
int sign; |
#ifdef BSD4_4 |
quad_t l; |
u_quad_t num; |
#else |
long l; |
u_long num; |
#endif |
unsigned base; |
int len; |
int size; |
int pad; |
while ((c = *f++) != '\0') { |
if (c != '%') { |
outc(c, dest); |
continue; |
} |
flushleft = 0; |
sharp = 0; |
width = 0; |
prec = -1; |
islong = 0; |
isquad = 0; |
for (;;) { |
if (*f == '-') |
flushleft++; |
else if (*f == '#') |
sharp++; |
else |
break; |
f++; |
} |
if (*f == '*') { |
width = va_arg(ap, int); |
f++; |
} else { |
while (is_digit(*f)) { |
width = 10 * width + digit_val(*f++); |
} |
} |
if (*f == '.') { |
if (*++f == '*') { |
prec = va_arg(ap, int); |
f++; |
} else { |
prec = 0; |
while (is_digit(*f)) { |
prec = 10 * prec + digit_val(*f++); |
} |
} |
} |
if (*f == 'l') { |
f++; |
if (*f == 'l') { |
isquad++; |
f++; |
} else |
islong++; |
} else if (*f == 'q') { |
isquad++; |
f++; |
} |
switch (*f) { |
case 'd': |
#ifdef BSD4_4 |
if (isquad) |
l = va_arg(ap, quad_t); |
else |
#endif |
if (islong) |
l = va_arg(ap, long); |
else |
l = va_arg(ap, int); |
sign = 0; |
num = l; |
if (l < 0) { |
num = -l; |
sign = 1; |
} |
base = 10; |
goto number; |
case 'u': |
base = 10; |
goto uns_number; |
case 'o': |
base = 8; |
goto uns_number; |
case 'p': |
outc('0', dest); |
outc('x', dest); |
/*FALLTHROUGH*/ |
case 'x': |
/* we don't implement 'x'; treat like 'X' */ |
case 'X': |
base = 16; |
uns_number: /* an unsigned number */ |
sign = 0; |
#ifdef BSD4_4 |
if (isquad) |
num = va_arg(ap, u_quad_t); |
else |
#endif |
if (islong) |
num = va_arg(ap, unsigned long); |
else |
num = va_arg(ap, unsigned int); |
number: /* process a number */ |
p = temp + TEMPSIZE - 1; |
*p = '\0'; |
while (num) { |
*--p = digit[num % base]; |
num /= base; |
} |
len = (temp + TEMPSIZE - 1) - p; |
if (prec < 0) |
prec = 1; |
if (sharp && *f == 'o' && prec <= len) |
prec = len + 1; |
pad = 0; |
if (width) { |
size = len; |
if (size < prec) |
size = prec; |
size += sign; |
pad = width - size; |
if (flushleft == 0) { |
while (--pad >= 0) |
outc(' ', dest); |
} |
} |
if (sign) |
outc('-', dest); |
prec -= len; |
while (--prec >= 0) |
outc('0', dest); |
while (*p) |
outc(*p++, dest); |
while (--pad >= 0) |
outc(' ', dest); |
break; |
case 's': |
p = va_arg(ap, char *); |
pad = 0; |
if (width) { |
len = strlen(p); |
if (prec >= 0 && len > prec) |
len = prec; |
pad = width - len; |
if (flushleft == 0) { |
while (--pad >= 0) |
outc(' ', dest); |
} |
} |
prec++; |
while (--prec != 0 && *p) |
outc(*p++, dest); |
while (--pad >= 0) |
outc(' ', dest); |
break; |
case 'c': |
c = va_arg(ap, int); |
outc(c, dest); |
break; |
default: |
outc(*f, dest); |
break; |
} |
f++; |
} |
#endif /* !HAVE_VASPRINTF */ |
} |
#endif |
/* |
* Version of write which resumes after a signal is caught. |
*/ |
int |
xwrite(fd, buf, nbytes) |
int fd; |
const char *buf; |
int nbytes; |
{ |
int ntry; |
int i; |
int n; |
n = nbytes; |
ntry = 0; |
for (;;) { |
i = write(fd, buf, n); |
if (i > 0) { |
if ((n -= i) <= 0) |
return nbytes; |
buf += i; |
ntry = 0; |
} else if (i == 0) { |
if (++ntry > 10) |
return nbytes - n; |
} else if (errno != EINTR) { |
return -1; |
} |
} |
} |
#ifdef notdef |
/* |
* Version of ioctl that retries after a signal is caught. |
* XXX unused function |
*/ |
int |
xioctl(fd, request, arg) |
int fd; |
unsigned long request; |
char * arg; |
{ |
int i; |
while ((i = ioctl(fd, request, arg)) == -1 && errno == EINTR); |
return i; |
} |
#endif |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
void initstreams() { |
output.stream = stdout; |
errout.stream = stderr; |
} |
void |
openmemout() { |
memout.stream = open_memstream(&memout.buf, &memout.bufsize); |
} |
void |
closememout() { |
INTOFF; |
fclose(memout.stream); |
memout.stream = NULL; |
INTON; |
} |
#endif |
/branches/dd/uspace/app/ash/parser.h |
---|
0,0 → 1,83 |
/* $NetBSD: parser.h,v 1.14 2000/07/27 04:09:28 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)parser.h 8.3 (Berkeley) 5/4/95 |
*/ |
/* control characters in argument strings */ |
#define CTLESC '\201' |
#define CTLVAR '\202' |
#define CTLENDVAR '\203' |
#define CTLBACKQ '\204' |
#define CTLQUOTE 01 /* ored with CTLBACKQ code if in quotes */ |
/* CTLBACKQ | CTLQUOTE == '\205' */ |
#define CTLARI '\206' |
#define CTLENDARI '\207' |
#define CTLQUOTEMARK '\210' |
/* variable substitution byte (follows CTLVAR) */ |
#define VSTYPE 0x0f /* type of variable substitution */ |
#define VSNUL 0x10 /* colon--treat the empty string as unset */ |
#define VSQUOTE 0x80 /* inside double quotes--suppress splitting */ |
/* values of VSTYPE field */ |
#define VSNORMAL 0x1 /* normal variable: $var or ${var} */ |
#define VSMINUS 0x2 /* ${var-text} */ |
#define VSPLUS 0x3 /* ${var+text} */ |
#define VSQUESTION 0x4 /* ${var?message} */ |
#define VSASSIGN 0x5 /* ${var=text} */ |
#define VSTRIMLEFT 0x6 /* ${var#pattern} */ |
#define VSTRIMLEFTMAX 0x7 /* ${var##pattern} */ |
#define VSTRIMRIGHT 0x8 /* ${var%pattern} */ |
#define VSTRIMRIGHTMAX 0x9 /* ${var%%pattern} */ |
#define VSLENGTH 0xa /* ${#var} */ |
/* |
* NEOF is returned by parsecmd when it encounters an end of file. It |
* must be distinct from NULL, so we use the address of a variable that |
* happens to be handy. |
*/ |
extern int tokpushback; |
#define NEOF ((union node *)&tokpushback) |
extern int whichprompt; /* 1 == PS1, 2 == PS2 */ |
union node *parsecmd(int); |
void fixredir(union node *, const char *, int); |
int goodname(char *); |
const char *getprompt(void *); |
/branches/dd/uspace/app/ash/jobs.h |
---|
0,0 → 1,98 |
/* $NetBSD: jobs.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)jobs.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* Mode argument to forkshell. Don't change FORK_FG or FORK_BG. */ |
#define FORK_FG 0 |
#define FORK_BG 1 |
#define FORK_NOJOB 2 |
/* |
* A job structure contains information about a job. A job is either a |
* single process or a set of processes contained in a pipeline. In the |
* latter case, pidlist will be non-NULL, and will point to a -1 terminated |
* array of pids. |
*/ |
struct procstat { |
pid_t pid; /* process id */ |
int status; /* status flags (defined above) */ |
char *cmd; /* text of command being run */ |
}; |
/* states */ |
#define JOBSTOPPED 1 /* all procs are stopped */ |
#define JOBDONE 2 /* all procs are completed */ |
struct job { |
struct procstat ps0; /* status of process */ |
struct procstat *ps; /* status or processes when more than one */ |
short nprocs; /* number of processes */ |
short pgrp; /* process group of this job */ |
char state; /* true if job is finished */ |
char used; /* true if this entry is in used */ |
char changed; /* true if status has changed */ |
#if JOBS |
char jobctl; /* job running under job control */ |
#endif |
}; |
extern short backgndpid; /* pid of last background process */ |
extern int job_warning; /* user was warned about stopped jobs */ |
void setjobctl (int); |
int killcmd (int, char **); |
int fgcmd (int, char **); |
int bgcmd (int, char **); |
int jobscmd (int, char **); |
void showjobs (int); |
int waitcmd (int, char **); |
int jobidcmd (int, char **); |
struct job *makejob (union node *, int); |
int forkshell (struct job *, union node *, int); |
int waitforjob (struct job *); |
int stoppedjobs (void); |
char *commandtext (union node *); |
#if ! JOBS |
#define setjobctl(on) /* do nothing */ |
#endif |
/branches/dd/uspace/app/ash/output.h |
---|
0,0 → 1,110 |
/* $NetBSD: output.h,v 1.14 1998/01/31 12:37:55 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)output.h 8.2 (Berkeley) 5/4/95 |
*/ |
#ifndef OUTPUT_INCL |
#ifdef __STDC__ |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
#include <stdio.h> |
#endif |
struct output { |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
FILE *stream; |
#endif |
char *nextc; |
int nleft; |
char *buf; |
int bufsize; |
int fd; |
short flags; |
}; |
extern struct output output; |
extern struct output errout; |
extern struct output memout; |
extern struct output *out1; |
extern struct output *out2; |
void outstr (const char *, struct output *); |
#ifndef _GNU_SOURCE |
void emptyoutbuf (struct output *); |
#endif |
void flushall (void); |
#ifndef _GNU_SOURCE |
void flushout (struct output *); |
#endif |
void freestdout (void); |
void outfmt (struct output *, const char *, ...) |
__attribute__((__format__(__printf__,2,3))); |
void out1fmt (const char *, ...) |
__attribute__((__format__(__printf__,1,2))); |
#if !defined(__GLIBC__) && !defined(__UCLIBC__) |
void dprintf (const char *, ...) |
__attribute__((__format__(__printf__,1,2))); |
#endif |
void fmtstr (char *, size_t, const char *, ...) |
__attribute__((__format__(__printf__,3,4))); |
#ifndef _GNU_SOURCE |
void doformat (struct output *, const char *, va_list); |
#endif |
int xwrite (int, const char *, int); |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
void initstreams (void); |
void openmemout (void); |
void closememout (void); |
#define outc(c, o) putc(c, (o)->stream) |
#define flushout(o) fflush((o)->stream) |
#define doformat(d, f, a) vfprintf((d)->stream, f, a) |
#else |
#define outc(c, file) (--(file)->nleft < 0? (emptyoutbuf(file), *(file)->nextc++ = (c)) : (*(file)->nextc++ = (c))) |
#endif |
#define out1c(c) outc(c, out1) |
#define out2c(c) outc(c, out2) |
#define out1str(s) outstr(s, out1) |
#define out2str(s) outstr(s, out2) |
#define OUTPUT_INCL |
#endif |
/branches/dd/uspace/app/ash/builtins.def |
---|
0,0 → 1,96 |
#!/bin/sh - |
# $NetBSD: builtins.def,v 1.15 2000/04/09 23:27:03 christos Exp $ |
# |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)builtins.def 8.4 (Berkeley) 5/4/95 |
# |
# This file lists all the builtin commands. The first column is the name |
# of a C routine. The -j flag, if present, specifies that this command |
# is to be excluded from systems without job control, and the -h flag, |
# if present specifies that this command is to be excluded from systems |
# based on the SMALL compile-time symbol. The rest of the line |
# specifies the command name or names used to run the command. The entry |
# for bltincmd, which is run when the user does not specify a command, must |
# come first. |
# |
# NOTE: bltincmd must come first! |
bltincmd builtin |
#alloccmd alloc |
bgcmd -j bg |
breakcmd break continue |
#catfcmd catf |
cdcmd cd chdir |
commandcmd command |
dotcmd . |
echocmd echo |
evalcmd eval |
execcmd exec |
exitcmd exit |
expcmd exp let |
exportcmd export readonly |
#exprcmd expr |
falsecmd false |
histcmd -h fc |
fgcmd -j fg |
getoptscmd getopts |
hashcmd hash |
jobidcmd jobid |
jobscmd jobs |
killcmd -j kill |
#linecmd line |
localcmd local |
#nlechocmd nlecho |
#printfcmd printf |
pwdcmd pwd |
readcmd read |
returncmd return |
setcmd set |
setvarcmd setvar |
shiftcmd shift |
trapcmd trap |
truecmd : true |
typecmd type |
umaskcmd umask |
unaliascmd unalias |
unsetcmd unset |
waitcmd wait |
#foocmd foo |
aliascmd alias |
ulimitcmd ulimit |
testcmd test [ |
timescmd times |
/branches/dd/uspace/app/ash/mystring.c |
---|
0,0 → 1,144 |
/* $NetBSD: mystring.c,v 1.14 1999/07/09 03:05:50 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)mystring.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: mystring.c,v 1.14 1999/07/09 03:05:50 christos Exp $"); |
#endif |
#endif /* not lint */ |
/* |
* String functions. |
* |
* equal(s1, s2) Return true if strings are equal. |
* scopy(from, to) Copy a string. |
* scopyn(from, to, n) Like scopy, but checks for overflow. |
* number(s) Convert a string of digits to an integer. |
* is_number(s) Return true if s is a string of digits. |
*/ |
#include <stdlib.h> |
#include "shell.h" |
#include "syntax.h" |
#include "error.h" |
#include "mystring.h" |
char nullstr[1]; /* zero length string */ |
/* |
* equal - #defined in mystring.h |
*/ |
/* |
* scopy - #defined in mystring.h |
*/ |
/* |
* scopyn - copy a string from "from" to "to", truncating the string |
* if necessary. "To" is always nul terminated, even if |
* truncation is performed. "Size" is the size of "to". |
*/ |
void |
scopyn(from, to, size) |
char const *from; |
char *to; |
int size; |
{ |
while (--size > 0) { |
if ((*to++ = *from++) == '\0') |
return; |
} |
*to = '\0'; |
} |
/* |
* prefix -- see if pfx is a prefix of string. |
*/ |
int |
prefix(pfx, string) |
char const *pfx; |
char const *string; |
{ |
while (*pfx) { |
if (*pfx++ != *string++) |
return 0; |
} |
return 1; |
} |
/* |
* Convert a string of digits to an integer, printing an error message on |
* failure. |
*/ |
int |
number(s) |
const char *s; |
{ |
if (! is_number(s)) |
error("Illegal number: %s", s); |
return atoi(s); |
} |
/* |
* Check for a valid number. This should be elsewhere. |
*/ |
int |
is_number(p) |
const char *p; |
{ |
do { |
if (! is_digit(*p)) |
return 0; |
} while (*++p != '\0'); |
return 1; |
} |
/branches/dd/uspace/app/ash/tags |
---|
0,0 → 1,1207 |
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ |
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ |
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/ |
!_TAG_PROGRAM_NAME Exuberant Ctags // |
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/ |
!_TAG_PROGRAM_VERSION 5.5.4 // |
ADDCMD setmode.c 170;" d file: |
ALIASINUSE alias.h 41;" d |
ALIGN machdep.h 52;" d |
ALL error.c 223;" d file: |
ARB exec.c 88;" d file: |
ARITH_ADD arith.c /^ ARITH_ADD = 275,$/;" e enum:yytokentype file: |
ARITH_ADD arith.c 114;" d file: |
ARITH_ADD arith.h /^ ARITH_ADD = 275,$/;" e enum:yytokentype |
ARITH_ADD arith.h 87;" d |
ARITH_AND arith.c /^ ARITH_AND = 262,$/;" e enum:yytokentype file: |
ARITH_AND arith.c 101;" d file: |
ARITH_AND arith.h /^ ARITH_AND = 262,$/;" e enum:yytokentype |
ARITH_AND arith.h 74;" d |
ARITH_BAND arith.c /^ ARITH_BAND = 265,$/;" e enum:yytokentype file: |
ARITH_BAND arith.c 104;" d file: |
ARITH_BAND arith.h /^ ARITH_BAND = 265,$/;" e enum:yytokentype |
ARITH_BAND arith.h 77;" d |
ARITH_BNOT arith.c /^ ARITH_BNOT = 279,$/;" e enum:yytokentype file: |
ARITH_BNOT arith.c 118;" d file: |
ARITH_BNOT arith.h /^ ARITH_BNOT = 279,$/;" e enum:yytokentype |
ARITH_BNOT arith.h 91;" d |
ARITH_BOR arith.c /^ ARITH_BOR = 263,$/;" e enum:yytokentype file: |
ARITH_BOR arith.c 102;" d file: |
ARITH_BOR arith.h /^ ARITH_BOR = 263,$/;" e enum:yytokentype |
ARITH_BOR arith.h 75;" d |
ARITH_BXOR arith.c /^ ARITH_BXOR = 264,$/;" e enum:yytokentype file: |
ARITH_BXOR arith.c 103;" d file: |
ARITH_BXOR arith.h /^ ARITH_BXOR = 264,$/;" e enum:yytokentype |
ARITH_BXOR arith.h 76;" d |
ARITH_DIV arith.c /^ ARITH_DIV = 277,$/;" e enum:yytokentype file: |
ARITH_DIV arith.c 116;" d file: |
ARITH_DIV arith.h /^ ARITH_DIV = 277,$/;" e enum:yytokentype |
ARITH_DIV arith.h 89;" d |
ARITH_EQ arith.c /^ ARITH_EQ = 267,$/;" e enum:yytokentype file: |
ARITH_EQ arith.c 106;" d file: |
ARITH_EQ arith.h /^ ARITH_EQ = 267,$/;" e enum:yytokentype |
ARITH_EQ arith.h 79;" d |
ARITH_GE arith.c /^ ARITH_GE = 269,$/;" e enum:yytokentype file: |
ARITH_GE arith.c 108;" d file: |
ARITH_GE arith.h /^ ARITH_GE = 269,$/;" e enum:yytokentype |
ARITH_GE arith.h 81;" d |
ARITH_GT arith.c /^ ARITH_GT = 270,$/;" e enum:yytokentype file: |
ARITH_GT arith.c 109;" d file: |
ARITH_GT arith.h /^ ARITH_GT = 270,$/;" e enum:yytokentype |
ARITH_GT arith.h 82;" d |
ARITH_LE arith.c /^ ARITH_LE = 268,$/;" e enum:yytokentype file: |
ARITH_LE arith.c 107;" d file: |
ARITH_LE arith.h /^ ARITH_LE = 268,$/;" e enum:yytokentype |
ARITH_LE arith.h 80;" d |
ARITH_LPAREN arith.c /^ ARITH_LPAREN = 259,$/;" e enum:yytokentype file: |
ARITH_LPAREN arith.c 98;" d file: |
ARITH_LPAREN arith.h /^ ARITH_LPAREN = 259,$/;" e enum:yytokentype |
ARITH_LPAREN arith.h 71;" d |
ARITH_LSHIFT arith.c /^ ARITH_LSHIFT = 273,$/;" e enum:yytokentype file: |
ARITH_LSHIFT arith.c 112;" d file: |
ARITH_LSHIFT arith.h /^ ARITH_LSHIFT = 273,$/;" e enum:yytokentype |
ARITH_LSHIFT arith.h 85;" d |
ARITH_LT arith.c /^ ARITH_LT = 271,$/;" e enum:yytokentype file: |
ARITH_LT arith.c 110;" d file: |
ARITH_LT arith.h /^ ARITH_LT = 271,$/;" e enum:yytokentype |
ARITH_LT arith.h 83;" d |
ARITH_MUL arith.c /^ ARITH_MUL = 278,$/;" e enum:yytokentype file: |
ARITH_MUL arith.c 117;" d file: |
ARITH_MUL arith.h /^ ARITH_MUL = 278,$/;" e enum:yytokentype |
ARITH_MUL arith.h 90;" d |
ARITH_NE arith.c /^ ARITH_NE = 266,$/;" e enum:yytokentype file: |
ARITH_NE arith.c 105;" d file: |
ARITH_NE arith.h /^ ARITH_NE = 266,$/;" e enum:yytokentype |
ARITH_NE arith.h 78;" d |
ARITH_NOT arith.c /^ ARITH_NOT = 280,$/;" e enum:yytokentype file: |
ARITH_NOT arith.c 119;" d file: |
ARITH_NOT arith.h /^ ARITH_NOT = 280,$/;" e enum:yytokentype |
ARITH_NOT arith.h 92;" d |
ARITH_NUM arith.c /^ ARITH_NUM = 258,$/;" e enum:yytokentype file: |
ARITH_NUM arith.c 97;" d file: |
ARITH_NUM arith.h /^ ARITH_NUM = 258,$/;" e enum:yytokentype |
ARITH_NUM arith.h 70;" d |
ARITH_OR arith.c /^ ARITH_OR = 261,$/;" e enum:yytokentype file: |
ARITH_OR arith.c 100;" d file: |
ARITH_OR arith.h /^ ARITH_OR = 261,$/;" e enum:yytokentype |
ARITH_OR arith.h 73;" d |
ARITH_REM arith.c /^ ARITH_REM = 276,$/;" e enum:yytokentype file: |
ARITH_REM arith.c 115;" d file: |
ARITH_REM arith.h /^ ARITH_REM = 276,$/;" e enum:yytokentype |
ARITH_REM arith.h 88;" d |
ARITH_RPAREN arith.c /^ ARITH_RPAREN = 260,$/;" e enum:yytokentype file: |
ARITH_RPAREN arith.c 99;" d file: |
ARITH_RPAREN arith.h /^ ARITH_RPAREN = 260,$/;" e enum:yytokentype |
ARITH_RPAREN arith.h 72;" d |
ARITH_RSHIFT arith.c /^ ARITH_RSHIFT = 272,$/;" e enum:yytokentype file: |
ARITH_RSHIFT arith.c 111;" d file: |
ARITH_RSHIFT arith.h /^ ARITH_RSHIFT = 272,$/;" e enum:yytokentype |
ARITH_RSHIFT arith.h 84;" d |
ARITH_SUB arith.c /^ ARITH_SUB = 274,$/;" e enum:yytokentype file: |
ARITH_SUB arith.c 113;" d file: |
ARITH_SUB arith.h /^ ARITH_SUB = 274,$/;" e enum:yytokentype |
ARITH_SUB arith.h 86;" d |
ARITH_UNARYMINUS arith.c /^ ARITH_UNARYMINUS = 282$/;" e enum:yytokentype file: |
ARITH_UNARYMINUS arith.c 121;" d file: |
ARITH_UNARYMINUS arith.h /^ ARITH_UNARYMINUS = 282$/;" e enum:yytokentype |
ARITH_UNARYMINUS arith.h 94;" d |
ARITH_UNARYPLUS arith.c /^ ARITH_UNARYPLUS = 281,$/;" e enum:yytokentype file: |
ARITH_UNARYPLUS arith.c 120;" d file: |
ARITH_UNARYPLUS arith.h /^ ARITH_UNARYPLUS = 281,$/;" e enum:yytokentype |
ARITH_UNARYPLUS arith.h 93;" d |
ATABSIZE alias.c 58;" d file: |
BAND bltin/test.c /^ BAND,$/;" e enum:token file: |
BBINOP bltin/test.c /^ BBINOP,$/;" e enum:token_types file: |
BINOP bltin/test.c /^ BINOP,$/;" e enum:token_types file: |
BITCMD setmode.c /^} BITCMD;$/;" t file: |
BLOCKSIZE mkinit.c 90;" d file: |
BLOCK_OUT output.c 81;" d file: |
BOR bltin/test.c /^ BOR,$/;" e enum:token file: |
BSD shell.h 57;" d |
BUFLEN mknodes.c 71;" d file: |
BUNOP bltin/test.c /^ BUNOP,$/;" e enum:token_types file: |
CEOF jobs.c 70;" d file: |
CEOF output.c 69;" d file: |
CHECKEND parser.c 839;" d file: |
CHECKSTRSPACE memalloc.h 73;" d |
CLEAR_PENDING_INT error.h 90;" d |
CMD2_CLR setmode.c 80;" d file: |
CMD2_GBITS setmode.c 82;" d file: |
CMD2_OBITS setmode.c 83;" d file: |
CMD2_SET setmode.c 81;" d file: |
CMD2_UBITS setmode.c 84;" d file: |
CMDBUILTIN exec.h 44;" d |
CMDFUNCTION exec.h 45;" d |
CMDNORMAL exec.h 43;" d |
CMDTABLESIZE exec.c 87;" d file: |
CMDUNKNOWN exec.h 42;" d |
CTLARI parser.h 48;" d |
CTLBACKQ parser.h 45;" d |
CTLENDARI parser.h 49;" d |
CTLENDVAR parser.h 44;" d |
CTLESC parser.h 42;" d |
CTLQUOTE parser.h 46;" d |
CTLQUOTEMARK parser.h 50;" d |
CTLVAR parser.h 43;" d |
Cflag options.h 62;" d |
DEFEDITOR histedit.c 70;" d file: |
DEFINE_OPTIONS options.c 53;" d file: |
DEFINE_OPTIONS options.c 55;" d file: |
DEL hetio.c 49;" d file: |
DO_ABS exec.h 58;" d |
DO_BRUTE exec.h 60;" d |
DO_ERR exec.h 57;" d |
DO_NOFUN exec.h 59;" d |
EMPTY redir.c 73;" d file: |
EOFMARKLEN parser.c 73;" d file: |
EOF_NLEFT input.c 77;" d file: |
EOI bltin/test.c /^ EOI,$/;" e enum:token file: |
ESC hetio.c 48;" d file: |
EV_BACKCMD eval.c 84;" d file: |
EV_EXIT eval.c 82;" d file: |
EV_TESTED eval.c 83;" d file: |
EXERROR error.h 71;" d |
EXEXEC error.h 73;" d |
EXINT error.h 70;" d |
EXP_CASE expand.h 59;" d |
EXP_FULL expand.h 55;" d |
EXP_RECORD expand.h 60;" d |
EXP_REDIR expand.h 58;" d |
EXP_TILDE expand.h 56;" d |
EXP_VARTILDE expand.h 57;" d |
EXSHELLPROC error.h 72;" d |
E_CREAT error.h 46;" d |
E_EXEC error.h 47;" d |
E_OPEN error.h 45;" d |
Eflag options.h 61;" d |
FILBDEV bltin/test.c /^ FILBDEV,$/;" e enum:token file: |
FILCDEV bltin/test.c /^ FILCDEV,$/;" e enum:token file: |
FILDIR bltin/test.c /^ FILDIR,$/;" e enum:token file: |
FILEQ bltin/test.c /^ FILEQ,$/;" e enum:token file: |
FILEX bltin/test.c /^ FILEX,$/;" e enum:token file: |
FILEXIST bltin/test.c /^ FILEXIST,$/;" e enum:token file: |
FILFIFO bltin/test.c /^ FILFIFO,$/;" e enum:token file: |
FILGID bltin/test.c /^ FILGID,$/;" e enum:token file: |
FILGZ bltin/test.c /^ FILGZ,$/;" e enum:token file: |
FILNT bltin/test.c /^ FILNT,$/;" e enum:token file: |
FILOT bltin/test.c /^ FILOT,$/;" e enum:token file: |
FILRD bltin/test.c /^ FILRD,$/;" e enum:token file: |
FILREG bltin/test.c /^ FILREG,$/;" e enum:token file: |
FILSGID bltin/test.c /^ FILSGID,$/;" e enum:token file: |
FILSOCK bltin/test.c /^ FILSOCK,$/;" e enum:token file: |
FILSTCK bltin/test.c /^ FILSTCK,$/;" e enum:token file: |
FILSUID bltin/test.c /^ FILSUID,$/;" e enum:token file: |
FILSYM bltin/test.c /^ FILSYM,$/;" e enum:token file: |
FILTT bltin/test.c /^ FILTT,$/;" e enum:token file: |
FILUID bltin/test.c /^ FILUID,$/;" e enum:token file: |
FILWR bltin/test.c /^ FILWR,$/;" e enum:token file: |
FORCEINTON error.h 89;" d |
FORK_BG jobs.h 43;" d |
FORK_FG jobs.h 42;" d |
FORK_NOJOB jobs.h 44;" d |
GENHEADERS Makefile /^GENHEADERS = \\$/;" m |
GENSRCS Makefile /^GENSRCS = builtins.c \\$/;" m |
HAVE_VASPRINTF output.c 359;" d file: |
INITARGS bltin/bltin.h 67;" d |
INITARGS bltin/bltin.h 73;" d |
INIT_DEPS Makefile /^INIT_DEPS = alias.c eval.c exec.c input.c jobs.c options.c parser.c \\$/;" m |
INTEQ bltin/test.c /^ INTEQ,$/;" e enum:token file: |
INTGE bltin/test.c /^ INTGE,$/;" e enum:token file: |
INTGT bltin/test.c /^ INTGT,$/;" e enum:token file: |
INTLE bltin/test.c /^ INTLE,$/;" e enum:token file: |
INTLT bltin/test.c /^ INTLT,$/;" e enum:token file: |
INTNE bltin/test.c /^ INTNE,$/;" e enum:token file: |
INTOFF error.h 87;" d |
INTON error.h 88;" d |
Iflag options.h 53;" d |
JOBDONE jobs.h 63;" d |
JOBS shell.h 55;" d |
JOBSTOPPED jobs.h 62;" d |
LIBC_PREFIX Makefile /^LIBC_PREFIX = ..\/..\/lib\/libc$/;" m |
LIBS Makefile /^LIBS = $(LIBC_PREFIX)\/libc.a$/;" m |
LPAREN bltin/test.c /^ LPAREN,$/;" e enum:token file: |
MAXCMDTEXT jobs.c 1073;" d file: |
MAXFIELDS mknodes.c 70;" d file: |
MAXHISTLOOPS histedit.c 69;" d file: |
MAXMBOXES mail.c 64;" d file: |
MAXPWD cd.c 299;" d file: |
MAXTYPES mknodes.c 69;" d file: |
MAX_HISTORY hetio.c 46;" d file: |
MEM_OUT output.c 82;" d file: |
MINSIZE memalloc.c 118;" d file: |
MKINIT shell.h 72;" d |
NEOF parser.h 76;" d |
NEWARGS exec.c 217;" d file: |
NOPTS options.h 68;" d |
NSIG mksignames.c 28;" d file: |
NULL bltin/bltin.h 70;" d |
NULL shell.h 63;" d |
NULL shell.h 68;" d |
OBJECTS Makefile /^OBJECTS := $(addsuffix .o,$(basename $(SOURCES)))$/;" m |
OPERAND bltin/test.c /^ OPERAND$/;" e enum:token file: |
OUTBUFSIZ output.c 80;" d file: |
OUTFILE mkinit.c 78;" d file: |
OUTPUT Makefile /^OUTPUT = sh$/;" m |
OUTPUT_ERR output.c 83;" d file: |
OUTPUT_INCL output.h 109;" d |
OUTTEMP mkinit.c 79;" d file: |
PAREN bltin/test.c /^ PAREN$/;" e enum:token_types file: |
PARSEARITH parser.c 844;" d file: |
PARSEBACKQNEW parser.c 843;" d file: |
PARSEBACKQOLD parser.c 842;" d file: |
PARSEREDIR parser.c 840;" d file: |
PARSESUB parser.c 841;" d file: |
PIPESIZE redir.c 75;" d file: |
PIPESIZE redir.c 77;" d file: |
PROFILE main.c 86;" d file: |
REDIR_BACKQ redir.h 43;" d |
REDIR_PUSH redir.h 42;" d |
RETURN parser.c 754;" d file: |
RETURN parser.c 822;" d file: |
RPAREN bltin/test.c /^ RPAREN,$/;" e enum:token file: |
RTLEN mksignames.c 36;" d file: |
RTLIM mksignames.c 37;" d file: |
SET_LEN setmode.c 71;" d file: |
SET_LEN_INCR setmode.c 72;" d file: |
SHSRCS Makefile /^SHSRCS = alias.c \\$/;" m |
SIGSSIZE main.c 217;" d file: |
SKIPBREAK eval.h 72;" d |
SKIPCONT eval.h 73;" d |
SKIPFILE eval.h 75;" d |
SKIPFUNC eval.h 74;" d |
SOFTINT_PREFIX Makefile /^SOFTINT_PREFIX = ..\/..\/lib\/softint$/;" m |
SOURCES Makefile /^SOURCES = ${SHSRCS} ${GENSRCS}$/;" m |
STACKSTRNUL memalloc.h 75;" d |
STADJUST memalloc.h 78;" d |
STANDARD_BITS setmode.c 186;" d file: |
STARTSTACKSTR memalloc.h 71;" d |
STATIC shell.h 71;" d |
STPUTC memalloc.h 72;" d |
STREQ bltin/test.c /^ STREQ,$/;" e enum:token file: |
STREZ bltin/test.c /^ STREZ,$/;" e enum:token file: |
STRGT bltin/test.c /^ STRGT,$/;" e enum:token file: |
STRLT bltin/test.c /^ STRLT,$/;" e enum:token file: |
STRNE bltin/test.c /^ STRNE,$/;" e enum:token file: |
STRNZ bltin/test.c /^ STRNZ,$/;" e enum:token file: |
STTOPC memalloc.h 77;" d |
STUNPUTC memalloc.h 76;" d |
S_CATCH trap.c 78;" d file: |
S_DFL trap.c 77;" d file: |
S_HARD_IGN trap.c 80;" d file: |
S_IGN trap.c 79;" d file: |
S_ISTXT setmode.c 68;" d file: |
S_RESET trap.c 81;" d file: |
TEMPSIZE output.c 354;" d file: |
TRACE shell.h 80;" d |
TRACE shell.h 82;" d |
T_INT mknodes.c 77;" d file: |
T_NODE mknodes.c 74;" d file: |
T_NODELIST mknodes.c 75;" d file: |
T_OTHER mknodes.c 78;" d file: |
T_STRING mknodes.c 76;" d file: |
T_TEMP mknodes.c 79;" d file: |
UNOP bltin/test.c /^ UNOP,$/;" e enum:token_types file: |
UNOT bltin/test.c /^ UNOT,$/;" e enum:token file: |
USTPUTC memalloc.h 74;" d |
VEXPORT var.h 46;" d |
VNOFUNC var.h 52;" d |
VREADONLY var.h 47;" d |
VSASSIGN parser.h 62;" d |
VSLENGTH parser.h 67;" d |
VSMINUS parser.h 59;" d |
VSNORMAL parser.h 58;" d |
VSNUL parser.h 54;" d |
VSPLUS parser.h 60;" d |
VSQUESTION parser.h 61;" d |
VSQUOTE parser.h 55;" d |
VSTACK var.h 50;" d |
VSTRFIXED var.h 48;" d |
VSTRIMLEFT parser.h 63;" d |
VSTRIMLEFTMAX parser.h 64;" d |
VSTRIMRIGHT parser.h 65;" d |
VSTRIMRIGHTMAX parser.h 66;" d |
VSTYPE parser.h 53;" d |
VTABSIZE var.c 75;" d file: |
VTEXTFIXED var.h 49;" d |
VUNSET var.h 51;" d |
Vflag options.h 60;" d |
YYABORT arith.c 744;" d file: |
YYACCEPT arith.c 743;" d file: |
YYBACKUP arith.c 756;" d file: |
YYBISON arith.c 47;" d file: |
YYBISON_VERSION arith.c 50;" d file: |
YYCOPY arith.c 477;" d file: |
YYCOPY arith.c 480;" d file: |
YYDEBUG arith.c 268;" d file: |
YYDPRINTF arith.c 836;" d file: |
YYDPRINTF arith.c 982;" d file: |
YYEMPTY arith.c 740;" d file: |
YYEOF arith.c 741;" d file: |
YYERRCODE arith.c 775;" d file: |
YYERROR arith.c 745;" d file: |
YYERROR_VERBOSE arith.c 273;" d file: |
YYERROR_VERBOSE arith.c 274;" d file: |
YYERROR_VERBOSE arith.c 276;" d file: |
YYFAIL arith.c 752;" d file: |
YYFINAL arith.c 510;" d file: |
YYFPRINTF arith.c 833;" d file: |
YYFREE arith.c 443;" d file: |
YYID arith.c /^YYID (i)$/;" f file: |
YYID arith.c 367;" d file: |
YYINITDEPTH arith.c 991;" d file: |
YYLAST arith.c 512;" d file: |
YYLEX arith.c 823;" d file: |
YYLEX arith.c 825;" d file: |
YYLLOC_DEFAULT arith.c 784;" d file: |
YYLSP_NEEDED arith.c 59;" d file: |
YYMALLOC arith.c 436;" d file: |
YYMAXDEPTH arith.c 1002;" d file: |
YYMAXUTOK arith.c 525;" d file: |
YYNNTS arith.c 517;" d file: |
YYNRULES arith.c 519;" d file: |
YYNSTATES arith.c 521;" d file: |
YYNTOKENS arith.c 515;" d file: |
YYPACT_NINF arith.c 660;" d file: |
YYPOPSTACK arith.c 1340;" d file: |
YYPURE arith.c 56;" d file: |
YYRECOVERING arith.c 754;" d file: |
YYRHSLOC arith.c 782;" d file: |
YYSIZE_MAXIMUM arith.c 344;" d file: |
YYSIZE_T arith.c 332;" d file: |
YYSIZE_T arith.c 334;" d file: |
YYSIZE_T arith.c 338;" d file: |
YYSIZE_T arith.c 340;" d file: |
YYSKELETON_NAME arith.c 53;" d file: |
YYSTACK_ALLOC arith.c 390;" d file: |
YYSTACK_ALLOC arith.c 394;" d file: |
YYSTACK_ALLOC arith.c 399;" d file: |
YYSTACK_ALLOC arith.c 422;" d file: |
YYSTACK_ALLOC_MAXIMUM arith.c 419;" d file: |
YYSTACK_ALLOC_MAXIMUM arith.c 425;" d file: |
YYSTACK_BYTES arith.c 469;" d file: |
YYSTACK_FREE arith.c 413;" d file: |
YYSTACK_FREE arith.c 423;" d file: |
YYSTACK_GAP_MAXIMUM arith.c 465;" d file: |
YYSTACK_RELOCATE arith.c 1428;" d file: |
YYSTACK_RELOCATE arith.c 496;" d file: |
YYSTYPE arith.c /^typedef int YYSTYPE;$/;" t file: |
YYSTYPE arith.h /^typedef int YYSTYPE;$/;" t |
YYSTYPE_IS_DECLARED arith.c 287;" d file: |
YYSTYPE_IS_DECLARED arith.h 102;" d |
YYSTYPE_IS_TRIVIAL arith.c 288;" d file: |
YYSTYPE_IS_TRIVIAL arith.h 103;" d |
YYTABLE_NINF arith.c 681;" d file: |
YYTERROR arith.c 774;" d file: |
YYTOKENTYPE arith.c 65;" d file: |
YYTOKENTYPE arith.h 38;" d |
YYTOKEN_TABLE arith.c 281;" d file: |
YYTRANSLATE arith.c 527;" d file: |
YYUNDEFTOK arith.c 524;" d file: |
YYUSE arith.c 360;" d file: |
YYUSE arith.c 362;" d file: |
YY_ arith.c 350;" d file: |
YY_ arith.c 354;" d file: |
YY_LOCATION_PRINT arith.c 810;" d file: |
YY_LOCATION_PRINT arith.c 815;" d file: |
YY_REDUCE_PRINT arith.c 972;" d file: |
YY_REDUCE_PRINT arith.c 985;" d file: |
YY_STACK_PRINT arith.c 934;" d file: |
YY_STACK_PRINT arith.c 984;" d file: |
YY_SYMBOL_PRINT arith.c 842;" d file: |
YY_SYMBOL_PRINT arith.c 983;" d file: |
_STDLIB_H arith.c 404;" d file: |
_STDLIB_H arith.c 432;" d file: |
_rmescapes expand.c /^_rmescapes(str, flag)$/;" f |
action error.c /^ short action; \/* operation which encountered the error *\/$/;" m struct:errname file: |
add mksyntax.c /^add(p, type)$/;" f file: |
addchar mkinit.c /^addchar(c, text)$/;" f |
addcmd setmode.c /^addcmd(set, op, who, oparg, mask)$/;" f file: |
addcmdentry exec.c /^addcmdentry(name, entry)$/;" f |
addfname expand.c /^addfname(name)$/;" f |
addglob expand.c /^addglob(pglob)$/;" f |
addstr mkinit.c /^addstr(s, text)$/;" f |
aexpr bltin/test.c /^aexpr(n)$/;" f file: |
aflag options.h 63;" d |
alias alias.h /^struct alias {$/;" s |
aliascmd alias.c /^aliascmd(argc, argv)$/;" f |
align machdep.h /^union align {$/;" u |
alloca arith.c 397;" d file: |
amiddecls mkinit.c /^int amiddecls; \/* for formatting *\/$/;" v |
andor parser.c /^andor() {$/;" f |
ap input.c /^ struct alias *ap; \/* if push was associated with an alias *\/$/;" m struct:strpush file: |
arg0 options.c /^char *arg0; \/* value of $0 *\/$/;" v |
argbackq expand.c /^struct nodelist *argbackq; \/* list of back quote expressions *\/$/;" v |
arglist expand.h /^struct arglist {$/;" s |
argptr options.c /^char **argptr; \/* argument list for builtin commands *\/$/;" v |
argstr expand.c /^argstr(p, flag)$/;" f |
arith arith.c /^arith(s)$/;" f |
arith_buf arith.c /^const char *arith_buf, *arith_startbuf;$/;" v |
arith_startbuf arith.c /^const char *arith_buf, *arith_startbuf;$/;" v |
atab alias.c /^struct alias *atab[ATABSIZE];$/;" v |
attyset var.h 110;" d |
backcmd eval.h /^struct backcmd { \/* result of evalbackcmd *\/$/;" s |
backgndpid jobs.c /^MKINIT short backgndpid = -1; \/* pid of last background process *\/$/;" v |
backquotelist parser.c /^struct nodelist *backquotelist;$/;" v |
base mksyntax.c /^static int base;$/;" v file: |
basebuf input.c /^char basebuf[BUFSIZ]; \/* buffer for top level input file *\/$/;" v |
basepf input.c /^MKINIT struct parsefile basepf; \/* top level input file *\/$/;" v |
basestrpush input.c /^ struct strpush basestrpush; \/* so pushing one is fast *\/$/;" m struct:parsefile file: |
bash_group_member bltin/test.c /^bash_group_member (gid)$/;" f file: |
begoff expand.c /^ int begoff; \/* offset of start of region *\/$/;" m struct:ifsregion file: |
bflag options.h 64;" d |
bgcmd jobs.c /^bgcmd(argc, argv)$/;" f |
binop bltin/test.c /^binop()$/;" f file: |
bitcmd setmode.c /^typedef struct bitcmd {$/;" s file: |
bits setmode.c /^ mode_t bits;$/;" m struct:bitcmd file: |
block mkinit.c /^struct block {$/;" s file: |
bltincmd eval.c /^bltincmd(argc, argv)$/;" f |
bltinlookup var.c /^bltinlookup(name, doall)$/;" f |
breakcmd eval.c /^breakcmd(argc, argv)$/;" f |
buf eval.h /^ char *buf; \/* buffer *\/$/;" m struct:backcmd |
buf input.c /^ char *buf; \/* input buffer *\/$/;" m struct:parsefile file: |
buf output.h /^ char *buf;$/;" m struct:output |
bufsize output.h /^ int bufsize;$/;" m struct:output |
builtinloc exec.c /^STATIC int builtinloc = -1; \/* index in path of %builtin, or -1 *\/$/;" v |
casematch expand.c /^casematch(pattern, val)$/;" f |
cdcmd cd.c /^cdcmd(argc, argv)$/;" f |
cdcomppath cd.c /^STATIC char *cdcomppath;$/;" v |
cfile mksyntax.c /^static FILE *cfile;$/;" v file: |
changed jobs.h /^ char changed; \/* true if status has changed *\/$/;" m struct:job |
changepath exec.c /^changepath(newval)$/;" f |
checkkwd parser.c /^MKINIT int checkkwd; \/* 1 == check for kwds, 2 == also eat newlines *\/$/;" v |
chkmail mail.c /^chkmail(silent)$/;" f |
ckfopen mkinit.c /^ckfopen(file, mode)$/;" f |
ckfree memalloc.h 81;" d |
ckmalloc memalloc.c /^ckmalloc(nbytes)$/;" f |
ckmalloc mkinit.c /^ckmalloc(nbytes)$/;" f |
ckrealloc memalloc.c /^ckrealloc(p, nbytes)$/;" f |
clear_traps trap.c /^clear_traps() {$/;" f |
clearcmdentry exec.c /^clearcmdentry(firstchange)$/;" f |
clearredir redir.c /^clearredir() {$/;" f |
closememout output.c /^closememout() {$/;" f |
closescript input.c /^closescript() {$/;" f |
cmd jobs.h /^ char *cmd; \/* text of command being run *\/$/;" m struct:procstat |
cmd miscbltin.c /^ int cmd;$/;" m struct:limits file: |
cmd setmode.c /^ char cmd;$/;" m struct:bitcmd file: |
cmd2 setmode.c /^ char cmd2;$/;" m struct:bitcmd file: |
cmdentry exec.h /^struct cmdentry {$/;" s |
cmdenviron eval.c /^struct strlist *cmdenviron;$/;" v |
cmdlookup exec.c /^cmdlookup(name, add)$/;" f |
cmdloop main.c /^cmdloop(top)$/;" f |
cmdname exec.c /^ char cmdname[ARB]; \/* name of command *\/$/;" m struct:tblentry file: |
cmdnextc jobs.c /^STATIC char *cmdnextc;$/;" v |
cmdnleft jobs.c /^STATIC int cmdnleft;$/;" v |
cmdputs jobs.c /^cmdputs(s)$/;" f |
cmdtable exec.c /^STATIC struct tblentry *cmdtable[CMDTABLESIZE];$/;" v |
cmdtxt jobs.c /^cmdtxt(n)$/;" f |
cmdtype exec.c /^ short cmdtype; \/* index identifying command *\/$/;" m struct:tblentry file: |
cmdtype exec.h /^ int cmdtype;$/;" m struct:cmdentry |
code mkinit.c /^ struct text code; \/* code for handling event *\/$/;" m struct:event file: |
command parser.c /^command() {$/;" f |
commandcmd exec.c /^commandcmd(argc, argv)$/;" f |
commandname error.c /^char *commandname;$/;" v |
commandname eval.c /^char *commandname;$/;" v |
commandtext jobs.c /^commandtext(n)$/;" f |
comment mkinit.c /^ char *comment; \/* comment describing routine *\/$/;" m struct:event file: |
comment mksyntax.c /^ char *comment;$/;" m struct:synclass file: |
compress_mode setmode.c /^compress_mode(set)$/;" f file: |
copyfd redir.c /^copyfd(from, to)$/;" f |
copyright mkinit.c /^static const char copyright[] =$/;" v file: |
copyright mknodes.c /^static const char copyright[] =$/;" v file: |
copyright mksyntax.c /^static const char copyright[] =$/;" v file: |
cp machdep.h /^ char *cp;$/;" m union:align |
curcmd main.c /^STATIC union node *curcmd;$/;" v |
curdir cd.c /^char *curdir = NULL; \/* current working directory *\/$/;" v |
curfile mkinit.c /^char *curfile; \/* current file *\/$/;" v |
curjob jobs.c /^short curjob; \/* current job *\/$/;" v |
curstr mknodes.c /^static struct str *curstr; \/* current structure *\/$/;" v file: |
cvtnum expand.c /^cvtnum(num, buf)$/;" f |
debug show.c /^int debug = 0;$/;" v |
debug show.c /^int debug = 1;$/;" v |
decl mknodes.c /^ char *decl; \/* declaration of field *\/$/;" m struct:field file: |
decls mkinit.c /^struct text decls; \/* declarations *\/$/;" v |
decode_signal trap.c /^int decode_signal(const char *string)$/;" f |
defines mkinit.c /^struct text defines; \/* #define statements *\/$/;" v |
defun exec.c /^defun(name, func)$/;" f |
delete_cmd_entry exec.c /^delete_cmd_entry() {$/;" f |
deletefuncs exec.c /^deletefuncs() {$/;" f |
describe_command exec.c /^describe_command(command, verbose)$/;" f |
digit output.c /^static const char digit[] = "0123456789ABCDEF";$/;" v file: |
digit_contig mksyntax.c /^static int digit_contig;\/* true if digits are contiguous *\/$/;" v file: |
digit_convert mksyntax.c /^digit_convert()$/;" f file: |
displayhist histedit.c /^int displayhist;$/;" v |
docd cd.c /^docd(dest, print)$/;" f |
dodecl mkinit.c /^dodecl(line1, fp)$/;" f |
doevent mkinit.c /^doevent(ep, fp, fname)$/;" f |
doformat output.c /^doformat(dest, f, ap)$/;" f |
doformat output.h 100;" d |
doinclude mkinit.c /^doinclude(line)$/;" f |
done mknodes.c /^ int done; \/* set if fully parsed *\/$/;" m struct:str file: |
doprompt parser.c /^int doprompt; \/* if set, prompt the user *\/$/;" v |
dotcmd main.c /^dotcmd(argc, argv)$/;" f |
dotrap trap.c /^dotrap() {$/;" f |
dowait jobs.c /^dowait(block, job)$/;" f |
dprintf output.c /^dprintf(const char *fmt, ...)$/;" f |
dumpmode setmode.c /^dumpmode(set)$/;" f file: |
dupredirect redir.c /^dupredirect(redir, f, memory)$/;" f |
editing histedit.c 87;" d file: |
eflag options.h 51;" d |
el histedit.c /^EditLine *el; \/* editline cookie *\/$/;" v |
el input.c /^EditLine *el; \/* cookie for editline package *\/$/;" v |
el_in histedit.c /^static FILE *el_in, *el_out;$/;" v file: |
el_out histedit.c /^static FILE *el_in, *el_out;$/;" v file: |
emptyoutbuf output.c /^emptyoutbuf(dest)$/;" f |
endoff expand.c /^ int endoff; \/* offset of end of region *\/$/;" m struct:ifsregion file: |
environment var.c /^environment() {$/;" f |
eofmark parser.c /^ char *eofmark; \/* string indicating end of input *\/$/;" m struct:heredoc file: |
equal mkinit.c 172;" d file: |
equal mystring.h 48;" d |
equalf bltin/test.c /^equalf (f1, f2)$/;" f file: |
errcode error.c /^ short errcode; \/* error number *\/$/;" m struct:errname file: |
errmsg error.c /^errmsg(e, action)$/;" f |
errname error.c /^struct errname {$/;" s file: |
error arith.c /^error(s)$/;" f |
error bltin/test.c /^error(const char *msg, ...)$/;" f file: |
error error.c /^error(const char *msg, ...)$/;" f |
error mkinit.c /^error(msg)$/;" f |
error mknodes.c /^error(const char *msg, ...)$/;" f file: |
errormsg error.c /^STATIC const struct errname errormsg[] = {$/;" v |
errout output.c /^struct output errout = {NULL, 0, NULL, 100, 2, 0};$/;" v |
errout output.c /^struct output errout = {NULL, NULL, 0, NULL, 0, 2, 0};$/;" v |
evalbackcmd eval.c /^evalbackcmd(n, result)$/;" f |
evalcase eval.c /^evalcase(n, flags)$/;" f |
evalcmd eval.c /^evalcmd(argc, argv)$/;" f |
evalcommand eval.c /^evalcommand(cmd, flags, backcmd)$/;" f |
evalfor eval.c /^evalfor(n, flags)$/;" f |
evalloop eval.c /^evalloop(n, flags)$/;" f |
evalpipe eval.c /^evalpipe(n)$/;" f |
evalskip eval.c /^MKINIT int evalskip; \/* set if we are skipping commands *\/$/;" v |
evalstring eval.c /^evalstring(s, flag)$/;" f |
evalsubshell eval.c /^evalsubshell(n, flags)$/;" f |
evaltree eval.c /^evaltree(n, flags)$/;" f |
evalvar expand.c /^evalvar(p, flag)$/;" f |
event mkinit.c /^struct event event[] = {$/;" v |
event mkinit.c /^struct event {$/;" s file: |
exception error.c /^int exception;$/;" v |
execcmd eval.c /^execcmd(argc, argv)$/;" f |
execinterp exec.c /^execinterp(argv, envp)$/;" f |
exerrno exec.c /^int exerrno = 0; \/* Last exec error *\/$/;" v |
exerror error.c /^exerror(int cond, const char *msg, ...)$/;" f |
exitcmd main.c /^exitcmd(argc, argv)$/;" f |
exitshell trap.c /^exitshell(status)$/;" f |
exitstatus eval.c /^int exitstatus; \/* exit status of last command *\/$/;" v |
exp arith.y /^exp: expr {$/;" l |
expandarg expand.c /^expandarg(arg, arglist, flag)$/;" f |
expandhere expand.c /^expandhere(arg, fd)$/;" f |
expandmeta expand.c /^expandmeta(str, flag)$/;" f |
exparg expand.c /^struct arglist exparg; \/* holds expanded arg list *\/$/;" v |
expari expand.c /^expari(flag)$/;" f |
expbackq expand.c /^expbackq(cmd, quoted, flag)$/;" f |
expcmd arith.c /^expcmd(argc, argv)$/;" f |
expdest expand.c /^char *expdest; \/* output of current string *\/$/;" v |
expdir expand.c /^char *expdir;$/;" v |
expmeta expand.c /^expmeta(enddir, name)$/;" f |
exportcmd var.c /^exportcmd(argc, argv)$/;" f |
expr arith.y /^expr: ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; }$/;" l |
expredir eval.c /^expredir(n)$/;" f |
expsort expand.c /^expsort(str)$/;" f |
exptilde expand.c /^exptilde(p, flag)$/;" f |
exraise error.c /^exraise(e)$/;" f |
exverror error.c /^exverror(cond, msg, ap)$/;" f file: |
factor miscbltin.c /^ int factor; \/* multiply by to get rlim_{cur,max} values *\/$/;" m struct:limits file: |
falsecmd eval.c /^falsecmd(argc, argv)$/;" f |
fc_replace histedit.c /^fc_replace(s, p, r)$/;" f |
fd eval.h /^ int fd; \/* file descriptor to read from *\/$/;" m struct:backcmd |
fd input.c /^ int fd; \/* file descriptor (or -1 if string) *\/$/;" m struct:parsefile file: |
fd output.h /^ int fd;$/;" m struct:output |
fd0_redirected redir.c /^int fd0_redirected = 0;$/;" v |
fd0_redirected_p redir.c /^fd0_redirected_p () {$/;" f |
fd2 redir.c /^int fd2 = 2;$/;" v |
fflag options.h 52;" d |
fflush bltin/bltin.h 60;" d |
fgcmd jobs.c /^fgcmd(argc, argv)$/;" f |
field mknodes.c /^ struct field field[MAXFIELDS]; \/* the fields of the structure *\/$/;" m struct:str file: |
field mknodes.c /^struct field { \/* a structure field *\/$/;" s file: |
filltable mksyntax.c /^filltable(dftval)$/;" f file: |
filstat bltin/test.c /^filstat(nm, mode)$/;" f file: |
find_builtin exec.c /^find_builtin(name)$/;" f |
find_command exec.c /^find_command(name, entry, act, path)$/;" f |
find_dot_file main.c /^find_dot_file(basename)$/;" f |
fixredir parser.c /^void fixredir(union node *n, const char *text, int err)$/;" f |
flag alias.h /^ int flag;$/;" m struct:alias |
flags output.h /^ short flags;$/;" m struct:output |
flags var.c /^ int flags;$/;" m struct:varinit file: |
flags var.h /^ int flags; \/* flags are defined above *\/$/;" m struct:var |
flags var.h /^ int flags; \/* saved flags *\/$/;" m struct:localvar |
flushall output.c /^flushall() {$/;" f |
flushout output.c /^flushout(dest)$/;" f |
flushout output.h 99;" d |
fmtstr output.c /^fmtstr(char *outbuf, size_t length, const char *fmt, ...)$/;" f |
forkshell jobs.c /^forkshell(jp, n, mode)$/;" f |
fprintf bltin/bltin.h 58;" d |
fputs bltin/bltin.h 59;" d |
freejob jobs.c /^freejob(jp)$/;" f |
freeparam options.c /^freeparam(param)$/;" f |
freestdout output.c /^freestdout() {$/;" f |
func exec.h /^ union node *func;$/;" m union:cmdentry::param |
func var.c /^ void (*func) __P((const char *));$/;" m struct:varinit file: |
func var.h /^ void (*func) __P((const char *));$/;" m struct:var |
funcnest eval.c /^int funcnest; \/* depth of function calls *\/$/;" v |
get_standard_path eval.c /^get_standard_path()$/;" f |
getcmdentry exec.c /^getcmdentry(name, entry)$/;" f |
getcomponent cd.c /^getcomponent() {$/;" f |
getjob jobs.c /^getjob(name)$/;" f |
getmode setmode.c /^getmode(bbox, omode)$/;" f |
getn bltin/test.c /^getn(s)$/;" f file: |
getopts options.c /^getopts(optstr, optvar, optfirst, optind, optoff)$/;" f |
getoptscmd options.c /^getoptscmd(argc, argv)$/;" f |
getoptsreset options.c /^getoptsreset(value)$/;" f |
getprompt parser.c /^getprompt(void *unused)$/;" f |
getpwd cd.c /^getpwd()$/;" f |
gooddefine mkinit.c /^gooddefine(line)$/;" f |
goodname parser.c /^goodname(char *name)$/;" f |
gotsig trap.c /^char gotsig[NSIG]; \/* indicates specified signal received *\/$/;" v |
gotsigchild jobs.c /^STATIC int gotsigchild;$/;" v |
grabstackblock memalloc.c /^grabstackblock(len)$/;" f |
grabstackstr memalloc.h 79;" d |
group_array bltin/test.c /^static gid_t *group_array = NULL;$/;" v file: |
growstackblock memalloc.c /^growstackblock() {$/;" f |
growstackstr memalloc.c /^growstackstr() {$/;" f |
handler error.c /^struct jmploc *handler;$/;" v |
hashalias alias.c /^hashalias(p)$/;" f |
hashcd exec.c /^hashcd() {$/;" f |
hashcmd exec.c /^hashcmd(argc, argv)$/;" f |
hashvar var.c /^hashvar(p)$/;" f |
header_files mkinit.c /^char *header_files[200]; \/* list of header files *\/$/;" v |
here parser.c /^ union node *here; \/* redirection node *\/$/;" m struct:heredoc file: |
heredoc parser.c /^struct heredoc *heredoc;$/;" v |
heredoc parser.c /^struct heredoc {$/;" s file: |
heredoclist parser.c /^struct heredoc *heredoclist; \/* list of here documents to read *\/$/;" v |
herefd memalloc.c /^int herefd = -1;$/;" v |
hetio_init hetio.c /^void hetio_init(void)$/;" f |
hetio_inter hetio.c /^int hetio_inter = 0;$/;" v |
hetio_read_input hetio.c /^int hetio_read_input(int fd)$/;" f |
hetio_reset_term hetio.c /^void hetio_reset_term(void)$/;" f |
hfile mksyntax.c /^static FILE *hfile;$/;" v file: |
his_end hetio.c /^static struct history *his_end = NULL; \/* Last element in command line list *\/$/;" v file: |
his_front hetio.c /^static struct history *his_front = NULL; \/* First element in command line list *\/$/;" v file: |
hist histedit.c /^History *hist; \/* history cookie *\/$/;" v |
histcmd histedit.c /^histcmd(argc, argv)$/;" f |
histedit histedit.c /^histedit()$/;" f |
history hetio.c /^struct history$/;" s file: |
history_counter hetio.c /^static int history_counter = 0; \/* Number of commands in history list *\/$/;" v file: |
histsizeval var.h 105;" d |
i machdep.h /^ int i;$/;" m union:align |
iflag options.h 54;" d |
ifsbreakup expand.c /^ifsbreakup(string, arglist)$/;" f |
ifsfirst expand.c /^struct ifsregion ifsfirst; \/* first struct in list of ifs regions *\/$/;" v |
ifsfree expand.c /^ifsfree()$/;" f |
ifslastp expand.c /^struct ifsregion *ifslastp; \/* last struct in list *\/$/;" v |
ifsregion expand.c /^struct ifsregion {$/;" s file: |
ifsset var.h 97;" d |
ifsval var.h 96;" d |
ignoresig trap.c /^ignoresig(signo)$/;" f |
in_function eval.h 67;" d |
indent mknodes.c /^indent(amount, fp)$/;" f file: |
indent show.c /^indent(amount, pfx, fp)$/;" f file: |
index exec.h /^ int index;$/;" m union:cmdentry::param |
infp mknodes.c /^static FILE *infp;$/;" v file: |
init mkinit.c /^char init[] = "\\$/;" v |
init mksyntax.c /^init()$/;" f file: |
init_editline input.c /^int init_editline = 0; \/* editline library initialized? *\/$/;" v |
initialize_group_array bltin/test.c /^initialize_group_array ()$/;" f file: |
initialize_signames mksignames.c /^initialize_signames ()$/;" f |
initialpgrp jobs.c /^int initialpgrp; \/* pgrp of shell on invocation *\/$/;" v |
initstreams output.c /^void initstreams() {$/;" f |
initvar var.c /^initvar() {$/;" f |
input_backspace hetio.c /^input_backspace(int *cursor, int *len)$/;" f |
input_delete hetio.c /^void input_delete(int cursor)$/;" f |
input_end hetio.c /^void input_end(int *cursor, int len)$/;" f |
input_home hetio.c /^void input_home(int *cursor) \/* Command line input routines *\/$/;" f |
int_pending error.h 91;" d |
intpending error.c /^volatile int intpending;$/;" v |
intreceived jobs.c /^STATIC int intreceived;$/;" v |
is_assignment_builtin eval.c /^is_assignment_builtin (command)$/;" f |
is_entry mksyntax.c /^struct synclass is_entry[] = {$/;" v |
is_number mystring.c /^is_number(p)$/;" f |
is_regular_builtin exec.c /^is_regular_builtin(name)$/;" f |
is_special_builtin eval.c /^is_special_builtin(name)$/;" f |
isoperand bltin/test.c /^isoperand()$/;" f file: |
jmploc error.h /^struct jmploc {$/;" s |
job jobs.h /^struct job {$/;" s |
job_warning jobs.c /^int job_warning = 0;$/;" v |
jobctl jobs.c /^MKINIT int jobctl;$/;" v |
jobctl jobs.h /^ char jobctl; \/* job running under job control *\/$/;" m struct:job |
jobidcmd jobs.c /^jobidcmd(argc, argv)$/;" f |
jobscmd jobs.c /^jobscmd(argc, argv)$/;" f |
jobtab jobs.c /^struct job *jobtab; \/* array of jobs *\/$/;" v |
jp eval.h /^ struct job *jp; \/* job structure for command *\/$/;" m struct:backcmd |
killcmd jobs.c /^killcmd(argc, argv)$/;" f |
last mkinit.c /^ struct block *last;$/;" m struct:text file: |
lastcmdentry exec.c /^struct tblentry **lastcmdentry;$/;" v |
lastp expand.h /^ struct strlist **lastp;$/;" m struct:arglist |
lasttoken parser.c /^int lasttoken; \/* last token read *\/$/;" v |
letter options.h /^ const char letter;$/;" m struct:optent |
limits miscbltin.c /^static const struct limits limits[] = {$/;" v file: |
limits miscbltin.c /^struct limits {$/;" s file: |
line mknodes.c /^static char line[1024];$/;" v file: |
linep mknodes.c /^static char *linep;$/;" v file: |
linno input.c /^ int linno; \/* current line *\/$/;" m struct:parsefile file: |
linno mkinit.c /^int linno; \/* current line *\/$/;" v |
linno mknodes.c /^static int linno;$/;" v file: |
list expand.h /^ struct strlist *list;$/;" m struct:arglist |
list parser.c /^list(nlflag)$/;" f |
listsetvar var.c /^listsetvar(list)$/;" f |
lleft input.c /^ int lleft; \/* number of chars left in this buffer *\/$/;" m struct:parsefile file: |
loc error.h /^ jmp_buf loc;$/;" m struct:jmploc |
localcmd var.c /^localcmd(argc, argv)$/;" f |
localvar var.h /^struct localvar {$/;" s |
localvars var.h /^struct localvar *localvars;$/;" v |
longjmp error.h 107;" d |
lookupalias alias.c /^lookupalias(name, check)$/;" f |
lookupvar var.c /^lookupvar(name)$/;" f |
loopnest eval.c /^MKINIT int loopnest; \/* current loop nesting level *\/$/;" v |
macro mksyntax.c /^static char *macro[] = {$/;" v file: |
mailtime mail.c /^STATIC time_t mailtime[MAXMBOXES]; \/* times of mailboxes *\/$/;" v |
mailval var.h 98;" d |
main arith.c /^main(argc, argv)$/;" f |
main bltin/bltin.h 72;" d |
main bltin/echo.c /^main(argc, argv) char **argv; {$/;" f |
main bltin/echo.c 45;" d file: |
main bltin/times.c /^int main() {$/;" f |
main bltin/times.c 12;" d file: |
main main.c /^main(argc, argv)$/;" f |
main mkinit.c /^main(argc, argv)$/;" f |
main mknodes.c /^main(argc, argv)$/;" f |
main mksignames.c /^main (argc, argv)$/;" f |
main mksyntax.c /^main(argc, argv)$/;" f |
makejob jobs.c /^makejob(node, nprocs)$/;" f |
makename parser.c /^makename() {$/;" f |
makestrspace memalloc.c /^makestrspace() {$/;" f |
malloc options.h /^ unsigned char malloc; \/* if parameter list dynamically allocated *\/$/;" m struct:shparam |
marknext memalloc.h /^ struct stackmark *marknext;$/;" m struct:stackmark |
markp memalloc.c /^struct stackmark *markp;$/;" v |
match mkinit.c /^match(name, line)$/;" f |
memout output.c /^struct output memout = {NULL, 0, NULL, 0, MEM_OUT, 0};$/;" v |
memout output.c /^struct output memout = {NULL, NULL, 0, NULL, 0, MEM_OUT, 0};$/;" v |
mflag options.h 55;" d |
minus_o options.c /^minus_o(name, val)$/;" f |
minusc options.c /^char *minusc; \/* argument to -c option *\/$/;" v |
mklocal var.c /^mklocal(name)$/;" f |
mpathset var.h 112;" d |
mpathval var.h 99;" d |
msg error.c /^ const char *msg; \/* text describing the error *\/$/;" m struct:errname file: |
msort expand.c /^msort(list, len)$/;" f |
n hetio.c /^ struct history *n;$/;" m struct:history file: |
name alias.h /^ char *name;$/;" m struct:alias |
name miscbltin.c /^ const char *name;$/;" m struct:limits file: |
name mkinit.c /^ char *name; \/* name of event (e.g. INIT) *\/$/;" m struct:event file: |
name mknodes.c /^ char *name; \/* name of field *\/$/;" m struct:field file: |
name mksyntax.c /^ char *name;$/;" m struct:synclass file: |
name options.h /^ const char *name;$/;" m struct:optent |
nbits mksyntax.c /^static int nbits; \/* number of bits in a character *\/$/;" v file: |
needprompt parser.c /^int needprompt; \/* true if interactive and at start of line *\/$/;" v |
new_term hetio.c /^static struct termios old_term, new_term; \/* Current termio and the previous termio before starting ash *\/$/;" v file: |
newerf bltin/test.c /^newerf (f1, f2)$/;" f file: |
nexpr bltin/test.c /^nexpr(n)$/;" f file: |
next alias.h /^ struct alias *next;$/;" m struct:alias |
next exec.c /^ struct tblentry *next; \/* next entry in hash chain *\/$/;" m struct:tblentry file: |
next expand.c /^ struct ifsregion *next; \/* next region in list *\/$/;" m struct:ifsregion file: |
next expand.h /^ struct strlist *next;$/;" m struct:strlist |
next mkinit.c /^ struct block *next;$/;" m struct:block file: |
next parser.c /^ struct heredoc *next; \/* next here document in list *\/$/;" m struct:heredoc file: |
next redir.c /^ struct redirtab *next;$/;" m struct:redirtab file: |
next var.h /^ struct localvar *next; \/* next local variable in list *\/$/;" m struct:localvar |
next var.h /^ struct var *next; \/* next entry in hash list *\/$/;" m struct:var |
nextc input.c /^ char *nextc; \/* next char in buffer *\/$/;" m struct:parsefile file: |
nextc mkinit.c /^ char *nextc;$/;" m struct:text file: |
nextc output.h /^ char *nextc;$/;" m struct:output |
nextfield mknodes.c /^nextfield(buf)$/;" f file: |
nextopt options.c /^nextopt(optstring)$/;" f |
nfields mknodes.c /^ int nfields; \/* number of fields in the structure *\/$/;" m struct:str file: |
nflag options.h 56;" d |
ngroups bltin/test.c /^static int ngroups;$/;" v file: |
njobs jobs.c /^int njobs; \/* size of array *\/$/;" v |
nleft eval.h /^ int nleft; \/* number of chars in buffer *\/$/;" m struct:backcmd |
nleft input.c /^ int nleft; \/* number of chars left in this line *\/$/;" m struct:parsefile file: |
nleft mkinit.c /^ int nleft;$/;" m struct:text file: |
nleft output.h /^ int nleft;$/;" m struct:output |
nmboxes mail.c /^STATIC int nmboxes; \/* number of mailboxes *\/$/;" v |
noclobberopen redir.c /^noclobberopen(fname)$/;" f |
nodename mknodes.c /^static char *nodename[MAXTYPES]; \/* names of the nodes *\/$/;" v file: |
nodestr mknodes.c /^static struct str *nodestr[MAXTYPES]; \/* type of structure used by the node *\/$/;" v file: |
noexpand parser.c /^noexpand(text)$/;" f |
not_fcnumber histedit.c /^not_fcnumber(s)$/;" f |
nparam options.h /^ int nparam; \/* # of positional parameters (without $0) *\/$/;" m struct:shparam |
nprocs jobs.h /^ short nprocs; \/* number of processes *\/$/;" m struct:job |
nstr mknodes.c /^static int nstr; \/* number of structures *\/$/;" v file: |
ntypes mknodes.c /^static int ntypes; \/* number of node types *\/$/;" v file: |
nullstr mystring.c /^char nullstr[1]; \/* zero length string *\/$/;" v |
nulonly expand.c /^ int nulonly; \/* search for nul bytes only *\/$/;" m struct:ifsregion file: |
number mystring.c /^number(s)$/;" f |
oexitstatus eval.c /^int oexitstatus; \/* saved exit status *\/$/;" v |
oexpr bltin/test.c /^oexpr(n)$/;" f file: |
old_term hetio.c /^static struct termios old_term, new_term; \/* Current termio and the previous termio before starting ash *\/$/;" v file: |
olderf bltin/test.c /^olderf (f1, f2)$/;" f file: |
onint error.c /^onint() {$/;" f |
onsig trap.c /^onsig(signo)$/;" f |
onsigchild jobs.c /^STATIC int onsigchild() {$/;" f |
op_num bltin/test.c /^ short op_num, op_type;$/;" m struct:t_op file: |
op_text bltin/test.c /^ const char *op_text;$/;" m struct:t_op file: |
op_type bltin/test.c /^ short op_num, op_type;$/;" m struct:t_op file: |
open_mem output.c /^open_mem(block, length, file)$/;" f |
openhere redir.c /^openhere(redir)$/;" f |
openmemout output.c /^openmemout() {$/;" f |
openredirect redir.c /^openredirect(redir)$/;" f |
opentrace show.c /^opentrace() {$/;" f |
ops bltin/test.c /^} const ops [] = {$/;" v file: |
optarg options.c /^char *optarg; \/* set by nextopt (like getopt) *\/$/;" v |
optent options.h /^struct optent {$/;" s |
optind options.h /^ int optind; \/* next parameter to be processed by getopts *\/$/;" m struct:shparam |
optindval var.h 103;" d |
option miscbltin.c /^ char option;$/;" m struct:limits file: |
options options.c /^options(cmdline)$/;" f |
optlist options.h /^struct optent optlist[NOPTS] = {$/;" v |
optoff options.h /^ int optoff; \/* used by getopts *\/$/;" m struct:shparam |
optptr options.c /^char *optptr; \/* used by nextopt *\/$/;" v |
optschanged options.c /^optschanged()$/;" f |
out1 output.c /^struct output *out1 = &output;$/;" v |
out1c output.h 104;" d |
out1fmt output.c /^out1fmt(const char *fmt, ...)$/;" f |
out1str output.h 106;" d |
out2 output.c /^struct output *out2 = &errout;$/;" v |
out2c output.h 105;" d |
out2str output.h 107;" d |
out_junk output.c /^char out_junk[16];$/;" v |
outc output.h 102;" d |
outc output.h 98;" d |
outfmt output.c /^outfmt(struct output *file, const char *fmt, ...)$/;" f |
outfunc mknodes.c /^outfunc(cfile, calcsize)$/;" f file: |
output mkinit.c /^output() {$/;" f |
output mknodes.c /^output(file)$/;" f file: |
output output.c /^struct output output = {NULL, 0, NULL, OUTBUFSIZ, 1, 0};$/;" v |
output output.c /^struct output output = {NULL, NULL, 0, NULL, 0, 1, 0};$/;" v |
output output.h /^struct output {$/;" s |
output_type_macros mksyntax.c /^output_type_macros()$/;" f file: |
outsizes mknodes.c /^outsizes(cfile)$/;" f file: |
outstr output.c /^outstr(p, file)$/;" f |
p hetio.c /^ struct history *p;$/;" m struct:history file: |
p options.h /^ char **p; \/* parameter list *\/$/;" m struct:shparam |
padvance exec.c /^padvance(path, name)$/;" f |
param exec.c /^ union param param; \/* definition of builtin function *\/$/;" m struct:tblentry file: |
param exec.h /^ union param {$/;" u struct:cmdentry |
parsebackquote parser.c /^int parsebackquote; \/* nonzero if we are inside backquotes *\/$/;" v |
parsecmd parser.c /^parsecmd(int interact)$/;" f |
parsefield mknodes.c /^parsefield()$/;" f file: |
parsefile input.c /^struct parsefile *parsefile = &basepf; \/* current input file *\/$/;" v |
parsefile input.c /^struct parsefile {$/;" s file: |
parsefname parser.c /^parsefname() {$/;" f |
parseheredoc parser.c /^parseheredoc() {$/;" f |
parselleft input.c /^MKINIT int parselleft; \/* copy of parsefile->lleft *\/$/;" v |
parsenextc input.c /^char *parsenextc; \/* copy of parsefile->nextc *\/$/;" v |
parsenleft input.c /^MKINIT int parsenleft; \/* copy of parsefile->nleft *\/$/;" v |
parsenode mknodes.c /^parsenode()$/;" f file: |
path_change exec.c /^path_change(newval, bltin)$/;" f |
pathopt exec.c /^const char *pathopt;$/;" v |
pathval var.h 100;" d |
patmatch expand.c /^patmatch(pattern, string, squoted)$/;" f |
patmatch2 expand.c /^patmatch2(pattern, string, squoted)$/;" f |
patmatch2 expand.c 131;" d file: |
peektoken parser.c /^peektoken() {$/;" f |
pendingsigs trap.c /^int pendingsigs; \/* indicates some signal received *\/$/;" v |
pfgets input.c /^pfgets(line, len)$/;" f |
pgetc input.c /^pgetc()$/;" f |
pgetc_macro input.h 66;" d |
pgrp jobs.h /^ short pgrp; \/* process group of this job *\/$/;" m struct:job |
pid jobs.h /^ pid_t pid; \/* process id *\/$/;" m struct:procstat |
pipeline parser.c /^pipeline() {$/;" f |
plinno input.c /^int plinno = 1; \/* input line number *\/$/;" v |
pmatch expand.c /^pmatch(pattern, string, squoted)$/;" f |
pointer shell.h /^typedef char *pointer;$/;" t |
pointer shell.h /^typedef void *pointer;$/;" t |
popallfiles input.c /^popallfiles() {$/;" f |
popfile input.c /^popfile() {$/;" f |
poplocalvars var.c /^poplocalvars() {$/;" f |
popredir redir.c /^popredir() {$/;" f |
popstackmark memalloc.c /^popstackmark(mark)$/;" f |
popstring input.c /^popstring()$/;" f |
preadbuffer input.c /^preadbuffer()$/;" f |
preadfd input.c /^preadfd()$/;" f file: |
prefix mystring.c /^prefix(pfx, string)$/;" f |
preglob expand.c /^preglob(str)$/;" f |
prehash eval.c /^prehash(n)$/;" f |
prev input.c /^ struct parsefile *prev; \/* preceding file on stack *\/$/;" m struct:parsefile file: |
prev input.c /^ struct strpush *prev; \/* preceding string on stack *\/$/;" m struct:strpush file: |
prev memalloc.c /^ struct stack_block *prev;$/;" m struct:stack_block file: |
prevcmd main.c /^STATIC union node *prevcmd;$/;" v |
prevdir cd.c /^char *prevdir; \/* previous working directory *\/$/;" v |
prevlleft input.c /^ int prevlleft;$/;" m struct:strpush file: |
prevnleft input.c /^ int prevnleft;$/;" m struct:strpush file: |
prevstring input.c /^ char *prevstring;$/;" m struct:strpush file: |
primary bltin/test.c /^primary(n)$/;" f file: |
print mksyntax.c /^print(name)$/;" f file: |
printentry exec.c /^printentry(cmdp, verbose)$/;" f |
printf bltin/bltin.h 55;" d |
procargs options.c /^procargs(argc, argv)$/;" f |
procstat jobs.h /^struct procstat {$/;" s |
profile_buf main.c /^short profile_buf[16384];$/;" v |
progname mksignames.c /^char *progname;$/;" v |
ps jobs.h /^ struct procstat *ps; \/* status or processes when more than one *\/$/;" m struct:job |
ps0 jobs.h /^ struct procstat ps0; \/* status of process *\/$/;" m struct:job |
ps1val var.h 101;" d |
ps2val var.h 102;" d |
pungetc input.c /^pungetc() {$/;" f |
pushfile input.c /^pushfile() {$/;" f |
pushstring input.c /^pushstring(s, len, ap)$/;" f |
putc bltin/bltin.h 56;" d |
putchar bltin/bltin.h 57;" d |
pwdcmd cd.c /^pwdcmd(argc, argv)$/;" f |
qflag options.h 66;" d |
quoteflag parser.c /^int quoteflag; \/* set if (part of) last token was quoted *\/$/;" v |
rcsid mkinit.c /^static const char rcsid[] =$/;" v file: |
rcsid mknodes.c /^static const char rcsid[] =$/;" v file: |
rcsid mksyntax.c /^static const char rcsid[] =$/;" v file: |
read_profile main.c /^read_profile(name)$/;" f |
readcmd miscbltin.c /^readcmd(argc, argv)$/;" f |
readcmdfile main.c /^readcmdfile(name)$/;" f |
readfile mkinit.c /^readfile(fname)$/;" f |
readline mknodes.c /^readline()$/;" f file: |
readtoken parser.c /^readtoken() {$/;" f |
readtoken1 parser.c /^readtoken1(firstc, syntax, eofmark, striptabs)$/;" f |
recordregion expand.c /^recordregion(start, end, nulonly)$/;" f |
redirect redir.c /^redirect(redir, flags)$/;" f |
redirlist redir.c /^MKINIT struct redirtab *redirlist;$/;" v |
redirnode parser.c /^union node *redirnode;$/;" v |
redirtab redir.c /^struct redirtab {$/;" s file: |
rehash exec.c /^ char rehash; \/* if set, cd done since entry created *\/$/;" m struct:tblentry file: |
removerecordregions expand.c /^removerecordregions(endoff)$/;" f |
renamed redir.c /^ short renamed[10];$/;" m struct:redirtab file: |
reset mkinit.c /^char reset[] = "\\$/;" v |
reset_term hetio.c /^static int reset_term = 0; \/* Set to true if the terminal needs to be reset upon exit *\/$/;" v file: |
restartjob jobs.c /^restartjob(jp)$/;" f |
returncmd eval.c /^returncmd(argc, argv)$/;" f |
rflag miscbltin.c 71;" d file: |
rlim_t miscbltin.c /^typedef enum __rlimit_resource rlim_t;$/;" t file: |
rmaliases alias.c /^rmaliases() {$/;" f |
rmescapes expand.c /^rmescapes(str)$/;" f |
rootpid main.c /^int rootpid;$/;" v |
rootshell main.c /^int rootshell;$/;" v |
routine mkinit.c /^ char *routine; \/* name of routine called on event *\/$/;" m struct:event file: |
s hetio.c /^ char *s;$/;" m struct:history file: |
savestr memalloc.c /^savestr(s)$/;" f |
savestr mkinit.c /^savestr(s)$/;" f |
savestr mknodes.c /^savestr(s)$/;" f file: |
sccsid arith.c /^static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5\/4\/95";$/;" v file: |
scopy mystring.h 49;" d |
scopyn mystring.c /^scopyn(from, to, size)$/;" f |
setIO hetio.c /^void setIO(struct termios *new, struct termios *old) \/* Set terminal IO to canonical mode, and save old term settings. *\/$/;" f |
setalias alias.c /^setalias(name, val)$/;" f |
setcmd options.c /^setcmd(argc, argv)$/;" f |
sethistsize histedit.c /^sethistsize(hs)$/;" f |
setinputfd input.c /^setinputfd(fd, push)$/;" f |
setinputfile input.c /^setinputfile(fname, push)$/;" f |
setinputstring input.c /^setinputstring(string, push)$/;" f |
setinteractive trap.c /^setinteractive(on)$/;" f |
setjmp error.h 106;" d |
setjobctl jobs.c /^setjobctl(on)$/;" f |
setjobctl jobs.h 97;" d |
setmode setmode.c /^setmode(p)$/;" f |
setoption options.c /^setoption(flag, val)$/;" f |
setparam options.c /^setparam(argv)$/;" f |
setprompt parser.c /^setprompt(which)$/;" f |
setsignal trap.c /^setsignal(signo)$/;" f |
setstackmark memalloc.c /^setstackmark(mark)$/;" f |
setterm histedit.c /^setterm(term)$/;" f |
setvar var.c /^setvar(name, val, flags)$/;" f |
setvarcmd var.c /^setvarcmd(argc, argv)$/;" f |
setvareq var.c /^setvareq(s, flags)$/;" f |
setvarsafe var.c /^setvarsafe(name, val, flags)$/;" f |
sflag options.h 57;" d |
sharg show.c /^sharg(arg, fp)$/;" f file: |
shcmd show.c /^shcmd(cmd, fp)$/;" f file: |
shellexec exec.c /^shellexec(argv, envp, path, idx)$/;" f |
shellparam options.c /^struct shparam shellparam; \/* current positional parameters *\/$/;" v |
shellproc mkinit.c /^char shellproc[] = "\\$/;" v |
shiftcmd options.c /^shiftcmd(argc, argv)$/;" f |
short arith.c 300;" d file: |
showjobs jobs.c /^showjobs(change)$/;" f |
showtree show.c /^showtree(n)$/;" f |
showvarscmd var.c /^showvarscmd(argc, argv)$/;" f |
shparam options.h /^struct shparam {$/;" s |
shprocvar var.c /^shprocvar() {$/;" f |
shtree show.c /^shtree(n, ind, pfx, fp)$/;" f file: |
sigmode trap.c /^MKINIT char sigmode[NSIG]; \/* current value of signal *\/$/;" v |
signal_names mksignames.c /^char *signal_names[2 * NSIG];$/;" v |
simplecmd parser.c /^simplecmd(rpp, redir)$/;" f |
size mksyntax.c /^static int size; \/* number of values which a char variable can have *\/$/;" v file: |
skipbl mknodes.c /^skipbl()$/;" f file: |
skipcount eval.c /^STATIC int skipcount; \/* number of levels to skip *\/$/;" v |
space memalloc.c /^ char space[MINSIZE];$/;" m struct:stack_block file: |
sstrnleft memalloc.c /^int sstrnleft;$/;" v |
stack_block memalloc.c /^struct stack_block {$/;" s file: |
stackbase memalloc.c /^struct stack_block stackbase;$/;" v |
stackblock memalloc.h 69;" d |
stackblocksize memalloc.h 70;" d |
stackmark memalloc.h /^struct stackmark {$/;" s |
stacknleft memalloc.c /^int stacknleft = MINSIZE;$/;" v |
stacknleft memalloc.h /^ int stacknleft;$/;" m struct:stackmark |
stacknxt memalloc.c /^char *stacknxt = stackbase.space;$/;" v |
stacknxt memalloc.h /^ char *stacknxt;$/;" m struct:stackmark |
stackp memalloc.c /^struct stack_block *stackp = &stackbase;$/;" v |
stackp memalloc.h /^ struct stack_block *stackp;$/;" m struct:stackmark |
stalloc memalloc.c /^stalloc(nbytes)$/;" f |
start mkinit.c /^ struct block *start;$/;" m struct:text file: |
startlinno parser.c /^int startlinno; \/* line # where last token started *\/$/;" v |
state jobs.h /^ char state; \/* true if job is finished *\/$/;" m struct:job |
status jobs.h /^ int status; \/* status flags (defined above) *\/$/;" m struct:procstat |
stderr bltin/bltin.h 54;" d |
stdout bltin/bltin.h 53;" d |
stoppedjobs jobs.c /^stoppedjobs()$/;" f |
str mknodes.c /^static struct str str[MAXTYPES]; \/* the structures *\/$/;" v file: |
str mknodes.c /^struct str { \/* struct representing a node structure *\/$/;" s file: |
str_to_event histedit.c /^str_to_event(str, last)$/;" f |
stream output.h /^ FILE *stream;$/;" m struct:output |
striptabs parser.c /^ int striptabs; \/* if set, strip leading tabs *\/$/;" m struct:heredoc file: |
strlist expand.h /^struct strlist {$/;" s |
strpush input.c /^ struct strpush *strpush; \/* for pushing strings at this level *\/$/;" m struct:parsefile file: |
strpush input.c /^struct strpush {$/;" s file: |
strtodest expand.c /^strtodest(p, quoted, allow_split)$/;" f |
stunalloc memalloc.c /^stunalloc(p)$/;" f |
subevalvar expand.c /^subevalvar(p, str, strloc, subtype, startloc, varflags)$/;" f |
suppressint error.c /^volatile int suppressint;$/;" v |
synclass mksyntax.c /^struct synclass synclass[] = {$/;" v |
synclass mksyntax.c /^struct synclass {$/;" s file: |
synerror parser.c /^synerror(msg)$/;" f |
synexpect parser.c /^synexpect(token)$/;" f |
syntax bltin/test.c /^syntax(op, msg)$/;" f file: |
syntax mksyntax.c /^static char *syntax[513];$/;" v file: |
t_lex bltin/test.c /^t_lex(s)$/;" f file: |
t_op bltin/test.c /^static struct t_op {$/;" s file: |
t_wp bltin/test.c /^static char **t_wp;$/;" v file: |
t_wp_op bltin/test.c /^static struct t_op const *t_wp_op;$/;" v file: |
tag mknodes.c /^ char *tag; \/* structure tag *\/$/;" m struct:str file: |
tblentry exec.c /^struct tblentry {$/;" s file: |
termval var.h 106;" d |
test_eaccess bltin/test.c /^test_eaccess (path, mode)$/;" f file: |
testcmd bltin/test.c /^testcmd(argc, argv)$/;" f |
text expand.h /^ char *text;$/;" m struct:strlist |
text mkinit.c /^ char text[BLOCKSIZE];$/;" m struct:block file: |
text mkinit.c /^struct text {$/;" s file: |
text var.c /^ const char *text;$/;" m struct:varinit file: |
text var.h /^ char *text; \/* name=value *\/$/;" m struct:var |
text var.h /^ char *text; \/* saved text *\/$/;" m struct:localvar |
token bltin/test.c /^enum token {$/;" g file: |
token_types bltin/test.c /^enum token_types {$/;" g file: |
tokpushback parser.c /^MKINIT int tokpushback; \/* last token pushed back *\/$/;" v |
trace show.c /^trace(const char *fmt, ...)$/;" f |
tracefile show.c /^FILE *tracefile;$/;" v |
trap trap.c /^char *trap[NSIG+1]; \/* trap handler commands *\/$/;" v |
trapcmd trap.c /^trapcmd(argc, argv)$/;" f |
trargs show.c /^trargs(ap)$/;" f |
trputc show.c /^trputc(c)$/;" f |
trputs show.c /^trputs(s)$/;" f |
trstring show.c /^trstring(s)$/;" f file: |
truecmd eval.c /^truecmd(argc, argv)$/;" f |
tryexec exec.c /^tryexec(cmd, argv, envp)$/;" f |
type mknodes.c /^ int type; \/* type of field *\/$/;" m struct:field file: |
typecmd exec.c /^typecmd(argc, argv)$/;" f |
u exec.h /^ } u;$/;" m struct:cmdentry |
uflag options.h 65;" d |
ulimitcmd miscbltin.c /^ulimitcmd(argc, argv)$/;" f |
umaskcmd miscbltin.c /^umaskcmd(argc, argv)$/;" f |
unalias alias.c /^unalias(name)$/;" f |
unaliascmd alias.c /^unaliascmd(argc, argv)$/;" f |
ungrabstackstr memalloc.c /^ungrabstackstr(s, p)$/;" f |
unsetcmd var.c /^unsetcmd(argc, argv)$/;" f |
unsetfunc exec.c /^unsetfunc(name)$/;" f |
unsetvar var.c /^unsetvar(s)$/;" f |
updatepwd cd.c /^updatepwd(dir)$/;" f |
used jobs.h /^ char used; \/* true if this entry is in used *\/$/;" m struct:job |
val alias.h /^ char *val;$/;" m struct:alias |
val options.h /^ char val;$/;" m struct:optent |
var var.c /^ struct var *var;$/;" m struct:varinit file: |
var var.h /^struct var {$/;" s |
varequal var.c /^varequal(p, q)$/;" f |
varinit var.c /^const struct varinit varinit[] = {$/;" v |
varinit var.c /^struct varinit {$/;" s file: |
varisset expand.c /^varisset(name, nulok)$/;" f |
vartab var.c /^struct var *vartab[VTABSIZE];$/;" v |
varvalue expand.c /^varvalue(name, quoted, allow_split)$/;" f |
vatty var.c /^struct var vatty;$/;" v |
vflag options.h 59;" d |
vhistsize var.c /^struct var vhistsize;$/;" v |
vifs var.c /^struct var vifs;$/;" v |
vmail var.c /^struct var vmail;$/;" v |
vmpath var.c /^struct var vmpath;$/;" v |
voptind var.c /^struct var voptind;$/;" v |
vp var.h /^ struct var *vp; \/* the variable that was made local *\/$/;" m struct:localvar |
vpath var.c /^struct var vpath;$/;" v |
vps1 var.c /^struct var vps1;$/;" v |
vps2 var.c /^struct var vps2;$/;" v |
vterm var.c /^struct var vterm;$/;" v |
vvers var.c /^struct var vvers;$/;" v |
waitcmd jobs.c /^waitcmd(argc, argv)$/;" f |
waitforjob jobs.c /^waitforjob(jp)$/;" f |
waitonint jobs.c /^STATIC void waitonint(int sig) {$/;" f |
waitproc jobs.c /^waitproc(block, status)$/;" f |
warnx bltin/bltin.h 61;" d |
whichprompt input.c /^int whichprompt; \/* 1 == PS1, 2 == PS2 *\/$/;" v |
wordtext parser.c /^char *wordtext; \/* text of last word returned by readtoken *\/$/;" v |
write_signames mksignames.c /^write_signames (stream)$/;" f |
writer mkinit.c /^char writer[] = "\\$/;" v |
writer mknodes.c /^char writer[] = "\\$/;" v |
writer mksyntax.c /^static char writer[] = "\\$/;" v file: |
writetext mkinit.c /^writetext(text, fp)$/;" f |
xflag options.h 58;" d |
xioctl output.c /^xioctl(fd, request, arg)$/;" f |
xwrite output.c /^xwrite(fd, buf, nbytes)$/;" f |
xxreadtoken parser.c /^xxreadtoken() {$/;" f |
yy_reduce_print arith.c /^yy_reduce_print (yyvsp, yyrule)$/;" f file: |
yy_stack_print arith.c /^yy_stack_print (bottom, top)$/;" f file: |
yy_symbol_print arith.c /^yy_symbol_print (yyoutput, yytype, yyvaluep)$/;" f file: |
yy_symbol_value_print arith.c /^yy_symbol_value_print (yyoutput, yytype, yyvaluep)$/;" f file: |
yyalloc arith.c /^union yyalloc$/;" u file: |
yychar arith.c /^int yychar;$/;" v |
yycheck arith.c /^static const yytype_int8 yycheck[] =$/;" v file: |
yyclearin arith.c 739;" d file: |
yydebug arith.c /^int yydebug;$/;" v |
yydefact arith.c /^static const yytype_uint8 yydefact[] =$/;" v file: |
yydefgoto arith.c /^static const yytype_int8 yydefgoto[] =$/;" v file: |
yydestruct arith.c /^yydestruct (yymsg, yytype, yyvaluep)$/;" f file: |
yyerrok arith.c 738;" d file: |
yyerror arith.c /^yyerror(s)$/;" f |
yylval arith.c /^YYSTYPE yylval;$/;" v |
yynerrs arith.c /^int yynerrs;$/;" v |
yypact arith.c /^static const yytype_int16 yypact[] =$/;" v file: |
yypgoto arith.c /^static const yytype_int8 yypgoto[] =$/;" v file: |
yyprhs arith.c /^static const yytype_uint8 yyprhs[] =$/;" v file: |
yyr1 arith.c /^static const yytype_uint8 yyr1[] =$/;" v file: |
yyr2 arith.c /^static const yytype_uint8 yyr2[] =$/;" v file: |
yyrhs arith.c /^static const yytype_int8 yyrhs[] =$/;" v file: |
yyrline arith.c /^static const yytype_uint8 yyrline[] =$/;" v file: |
yyss arith.c /^ yytype_int16 yyss;$/;" m union:yyalloc file: |
yystos arith.c /^static const yytype_uint8 yystos[] =$/;" v file: |
yystpcpy arith.c /^yystpcpy (yydest, yysrc)$/;" f file: |
yystpcpy arith.c 1034;" d file: |
yystrlen arith.c /^yystrlen (yystr)$/;" f file: |
yystrlen arith.c 1011;" d file: |
yystype arith.c 286;" d file: |
yystype arith.h 101;" d |
yysyntax_error arith.c /^yysyntax_error (char *yyresult, int yystate, int yychar)$/;" f file: |
yytable arith.c /^static const yytype_uint8 yytable[] =$/;" v file: |
yytname arith.c /^static const char *const yytname[] =$/;" v file: |
yytnamerr arith.c /^yytnamerr (char *yyres, const char *yystr)$/;" f file: |
yytokentype arith.c /^ enum yytokentype {$/;" g file: |
yytokentype arith.h /^ enum yytokentype {$/;" g |
yytoknum arith.c /^static const yytype_uint16 yytoknum[] =$/;" v file: |
yytranslate arith.c /^static const yytype_uint8 yytranslate[] =$/;" v file: |
yytype_int16 arith.c /^typedef YYTYPE_INT16 yytype_int16;$/;" t file: |
yytype_int16 arith.c /^typedef short int yytype_int16;$/;" t file: |
yytype_int8 arith.c /^typedef YYTYPE_INT8 yytype_int8;$/;" t file: |
yytype_int8 arith.c /^typedef short int yytype_int8;$/;" t file: |
yytype_int8 arith.c /^typedef signed char yytype_int8;$/;" t file: |
yytype_uint16 arith.c /^typedef YYTYPE_UINT16 yytype_uint16;$/;" t file: |
yytype_uint16 arith.c /^typedef unsigned short int yytype_uint16;$/;" t file: |
yytype_uint8 arith.c /^typedef YYTYPE_UINT8 yytype_uint8;$/;" t file: |
yytype_uint8 arith.c /^typedef unsigned char yytype_uint8;$/;" t file: |
yyvs arith.c /^ YYSTYPE yyvs;$/;" m union:yyalloc file: |
/branches/dd/uspace/app/ash/histedit.c |
---|
0,0 → 1,513 |
/* $NetBSD: histedit.c,v 1.24 2000/11/06 04:21:14 mycroft Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)histedit.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: histedit.c,v 1.24 2000/11/06 04:21:14 mycroft Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/param.h> |
#include <paths.h> |
#include <stdio.h> |
#include <stdlib.h> |
#include <unistd.h> |
/* |
* Editline and history functions (and glue). |
*/ |
#include "shell.h" |
#include "parser.h" |
#include "var.h" |
#include "options.h" |
#include "main.h" |
#include "output.h" |
#include "mystring.h" |
#include "error.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#include "eval.h" |
#include "memalloc.h" |
#define MAXHISTLOOPS 4 /* max recursions through fc */ |
#define DEFEDITOR "ed" /* default editor *should* be $EDITOR */ |
History *hist; /* history cookie */ |
EditLine *el; /* editline cookie */ |
int displayhist; |
static FILE *el_in, *el_out; |
STATIC const char *fc_replace (const char *, char *, char *); |
/* |
* Set history and editing status. Called whenever the status may |
* have changed (figures out what to do). |
*/ |
void |
histedit() |
{ |
#define editing (Eflag || Vflag) |
if (iflag) { |
if (!hist) { |
/* |
* turn history on |
*/ |
INTOFF; |
hist = history_init(); |
INTON; |
if (hist != NULL) |
sethistsize(histsizeval()); |
else |
out2str("sh: can't initialize history\n"); |
} |
if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ |
/* |
* turn editing on |
*/ |
INTOFF; |
if (el_in == NULL) |
el_in = fdopen(0, "r"); |
if (el_out == NULL) |
el_out = fdopen(2, "w"); |
if (el_in == NULL || el_out == NULL) |
goto bad; |
el = el_init(arg0, el_in, el_out, el_out); |
if (el != NULL) { |
if (hist) |
el_set(el, EL_HIST, history, hist); |
el_set(el, EL_PROMPT, getprompt); |
} else { |
bad: |
out2str("sh: can't initialize editing\n"); |
} |
INTON; |
} else if (!editing && el) { |
INTOFF; |
el_end(el); |
el = NULL; |
INTON; |
} |
if (el) { |
if (Vflag) |
el_set(el, EL_EDITOR, "vi"); |
else if (Eflag) |
el_set(el, EL_EDITOR, "emacs"); |
el_source(el, NULL); |
} |
} else { |
INTOFF; |
if (el) { /* no editing if not interactive */ |
el_end(el); |
el = NULL; |
} |
if (hist) { |
history_end(hist); |
hist = NULL; |
} |
INTON; |
} |
} |
void |
sethistsize(hs) |
const char *hs; |
{ |
int histsize; |
HistEvent he; |
if (hist != NULL) { |
if (hs == NULL || *hs == '\0' || |
(histsize = atoi(hs)) < 0) |
histsize = 100; |
history(hist, &he, H_SETSIZE, histsize); |
} |
} |
void |
setterm(term) |
const char *term; |
{ |
if (el != NULL && term != NULL) |
if (el_set(el, EL_TERMINAL, term) != 0) { |
outfmt(out2, "sh: Can't set terminal type %s\n", term); |
outfmt(out2, "sh: Using dumb terminal settings.\n"); |
} |
} |
/* |
* This command is provided since POSIX decided to standardize |
* the Korn shell fc command. Oh well... |
*/ |
int |
histcmd(argc, argv) |
int argc; |
char **argv; |
{ |
int ch; |
const char *editor = NULL; |
HistEvent he; |
int lflg = 0, nflg = 0, rflg = 0, sflg = 0; |
int i, retval; |
const char *firststr, *laststr; |
int first, last, direction; |
char *pat = NULL, *repl; /* ksh "fc old=new" crap */ |
static int active = 0; |
struct jmploc jmploc; |
struct jmploc *volatile savehandler; |
char editfile[MAXPATHLEN + 1]; |
FILE *efp; |
#ifdef __GNUC__ |
/* Avoid longjmp clobbering */ |
(void) &editor; |
(void) &lflg; |
(void) &nflg; |
(void) &rflg; |
(void) &sflg; |
(void) &firststr; |
(void) &laststr; |
(void) &pat; |
(void) &repl; |
(void) &efp; |
(void) &argc; |
(void) &argv; |
#endif |
if (hist == NULL) |
error("history not active"); |
if (argc == 1) |
error("missing history argument"); |
#ifdef __GLIBC__ |
optind = 1; |
#else |
optreset = 1; optind = 1; /* initialize getopt */ |
#endif |
while (not_fcnumber(argv[optind]) && |
(ch = getopt(argc, argv, ":e:lnrs")) != -1) |
switch ((char)ch) { |
case 'e': |
editor = optarg; |
break; |
case 'l': |
lflg = 1; |
break; |
case 'n': |
nflg = 1; |
break; |
case 'r': |
rflg = 1; |
break; |
case 's': |
sflg = 1; |
break; |
case ':': |
error("option -%c expects argument", optopt); |
/* NOTREACHED */ |
case '?': |
default: |
error("unknown option: -%c", optopt); |
/* NOTREACHED */ |
} |
argc -= optind, argv += optind; |
/* |
* If executing... |
*/ |
if (lflg == 0 || editor || sflg) { |
lflg = 0; /* ignore */ |
editfile[0] = '\0'; |
/* |
* Catch interrupts to reset active counter and |
* cleanup temp files. |
*/ |
if (setjmp(jmploc.loc)) { |
active = 0; |
if (*editfile) |
unlink(editfile); |
handler = savehandler; |
longjmp(handler->loc, 1); |
} |
savehandler = handler; |
handler = &jmploc; |
if (++active > MAXHISTLOOPS) { |
active = 0; |
displayhist = 0; |
error("called recursively too many times"); |
} |
/* |
* Set editor. |
*/ |
if (sflg == 0) { |
if (editor == NULL && |
(editor = bltinlookup("FCEDIT", 1)) == NULL && |
(editor = bltinlookup("EDITOR", 1)) == NULL) |
editor = DEFEDITOR; |
if (editor[0] == '-' && editor[1] == '\0') { |
sflg = 1; /* no edit */ |
editor = NULL; |
} |
} |
} |
/* |
* If executing, parse [old=new] now |
*/ |
if (lflg == 0 && argc > 0 && |
((repl = strchr(argv[0], '=')) != NULL)) { |
pat = argv[0]; |
*repl++ = '\0'; |
argc--, argv++; |
} |
/* |
* determine [first] and [last] |
*/ |
switch (argc) { |
case 0: |
firststr = lflg ? "-16" : "-1"; |
laststr = "-1"; |
break; |
case 1: |
firststr = argv[0]; |
laststr = lflg ? "-1" : argv[0]; |
break; |
case 2: |
firststr = argv[0]; |
laststr = argv[1]; |
break; |
default: |
error("too many args"); |
/* NOTREACHED */ |
} |
/* |
* Turn into event numbers. |
*/ |
first = str_to_event(firststr, 0); |
last = str_to_event(laststr, 1); |
if (rflg) { |
i = last; |
last = first; |
first = i; |
} |
/* |
* XXX - this should not depend on the event numbers |
* always increasing. Add sequence numbers or offset |
* to the history element in next (diskbased) release. |
*/ |
direction = first < last ? H_PREV : H_NEXT; |
/* |
* If editing, grab a temp file. |
*/ |
if (editor) { |
int fd; |
INTOFF; /* easier */ |
sprintf(editfile, "%s_shXXXXXX", _PATH_TMP); |
if ((fd = mkstemp(editfile)) < 0) |
error("can't create temporary file %s", editfile); |
if ((efp = fdopen(fd, "w")) == NULL) { |
close(fd); |
error("can't allocate stdio buffer for temp"); |
} |
} |
/* |
* Loop through selected history events. If listing or executing, |
* do it now. Otherwise, put into temp file and call the editor |
* after. |
* |
* The history interface needs rethinking, as the following |
* convolutions will demonstrate. |
*/ |
history(hist, &he, H_FIRST); |
retval = history(hist, &he, H_NEXT_EVENT, first); |
for (;retval != -1; retval = history(hist, &he, direction)) { |
if (lflg) { |
if (!nflg) |
out1fmt("%5d ", he.num); |
out1str(he.str); |
} else { |
const char *s = pat ? |
fc_replace(he.str, pat, repl) : he.str; |
char *sp; |
if (sflg) { |
if (displayhist) { |
out2str(s); |
} |
evalstring(strcpy(stalloc(strlen(s) + 1), s), 0); |
free(sp); |
if (displayhist && hist) { |
/* |
* XXX what about recursive and |
* relative histnums. |
*/ |
history(hist, &he, H_ENTER, s); |
} |
} else |
fputs(s, efp); |
} |
/* |
* At end? (if we were to lose last, we'd sure be |
* messed up). |
*/ |
if (he.num == last) |
break; |
} |
if (editor) { |
char *editcmd; |
fclose(efp); |
editcmd = stalloc(strlen(editor) + strlen(editfile) + 2); |
sprintf(editcmd, "%s %s", editor, editfile); |
evalstring(editcmd, 0); /* XXX - should use no JC command */ |
INTON; |
readcmdfile(editfile); /* XXX - should read back - quick tst */ |
unlink(editfile); |
} |
if (lflg == 0 && active > 0) |
--active; |
if (displayhist) |
displayhist = 0; |
return 0; |
} |
STATIC const char * |
fc_replace(s, p, r) |
const char *s; |
char *p, *r; |
{ |
char *dest; |
int plen = strlen(p); |
STARTSTACKSTR(dest); |
while (*s) { |
if (*s == *p && strncmp(s, p, plen) == 0) { |
while (*r) |
STPUTC(*r++, dest); |
s += plen; |
*p = '\0'; /* so no more matches */ |
} else |
STPUTC(*s++, dest); |
} |
STACKSTRNUL(dest); |
dest = grabstackstr(dest); |
return (dest); |
} |
int |
not_fcnumber(s) |
char *s; |
{ |
if (s == NULL) |
return 0; |
if (*s == '-') |
s++; |
return (!is_number(s)); |
} |
int |
str_to_event(str, last) |
const char *str; |
int last; |
{ |
HistEvent he; |
const char *s = str; |
int relative = 0; |
int i, retval; |
retval = history(hist, &he, H_FIRST); |
switch (*s) { |
case '-': |
relative = 1; |
/*FALLTHROUGH*/ |
case '+': |
s++; |
} |
if (is_number(s)) { |
i = atoi(s); |
if (relative) { |
while (retval != -1 && i--) { |
retval = history(hist, &he, H_NEXT); |
} |
if (retval == -1) |
retval = history(hist, &he, H_LAST); |
} else { |
retval = history(hist, &he, H_NEXT_EVENT, i); |
if (retval == -1) { |
/* |
* the notion of first and last is |
* backwards to that of the history package |
*/ |
retval = history(hist, &he, |
last ? H_FIRST : H_LAST); |
} |
} |
if (retval == -1) |
error("history number %s not found (internal error)", |
str); |
} else { |
/* |
* pattern |
*/ |
retval = history(hist, &he, H_PREV_STR, str); |
if (retval == -1) |
error("history pattern not found: %s", str); |
} |
return (he.num); |
} |
#else |
int |
histcmd(argc, argv) |
int argc; |
char **argv; |
{ |
error("not compiled with history support"); |
/* NOTREACHED */ |
} |
#endif |
/branches/dd/uspace/app/ash/show.c |
---|
0,0 → 1,447 |
/* $NetBSD: show.c,v 1.18 1999/10/08 21:10:44 pk Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: show.c,v 1.18 1999/10/08 21:10:44 pk Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdio.h> |
#ifdef __STDC__ |
#include <stdarg.h> |
#else |
#include <varargs.h> |
#endif |
#include "shell.h" |
#include "parser.h" |
#include "nodes.h" |
#include "mystring.h" |
#include "show.h" |
#ifdef DEBUG |
static void shtree (union node *, int, char *, FILE*); |
static void shcmd (union node *, FILE *); |
static void sharg (union node *, FILE *); |
static void indent (int, char *, FILE *); |
static void trstring (char *); |
void |
showtree(n) |
union node *n; |
{ |
trputs("showtree called\n"); |
shtree(n, 1, NULL, stdout); |
} |
static void |
shtree(n, ind, pfx, fp) |
union node *n; |
int ind; |
char *pfx; |
FILE *fp; |
{ |
struct nodelist *lp; |
const char *s; |
if (n == NULL) |
return; |
indent(ind, pfx, fp); |
switch(n->type) { |
case NSEMI: |
s = "; "; |
goto binop; |
case NAND: |
s = " && "; |
goto binop; |
case NOR: |
s = " || "; |
binop: |
shtree(n->nbinary.ch1, ind, NULL, fp); |
/* if (ind < 0) */ |
fputs(s, fp); |
shtree(n->nbinary.ch2, ind, NULL, fp); |
break; |
case NCMD: |
shcmd(n, fp); |
if (ind >= 0) |
putc('\n', fp); |
break; |
case NPIPE: |
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { |
shcmd(lp->n, fp); |
if (lp->next) |
fputs(" | ", fp); |
} |
if (n->npipe.backgnd) |
fputs(" &", fp); |
if (ind >= 0) |
putc('\n', fp); |
break; |
default: |
fprintf(fp, "<node type %d>", n->type); |
if (ind >= 0) |
putc('\n', fp); |
break; |
} |
} |
static void |
shcmd(cmd, fp) |
union node *cmd; |
FILE *fp; |
{ |
union node *np; |
int first; |
const char *s; |
int dftfd; |
first = 1; |
for (np = cmd->ncmd.args ; np ; np = np->narg.next) { |
if (! first) |
putchar(' '); |
sharg(np, fp); |
first = 0; |
} |
for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) { |
if (! first) |
putchar(' '); |
switch (np->nfile.type) { |
case NTO: s = ">"; dftfd = 1; break; |
case NAPPEND: s = ">>"; dftfd = 1; break; |
case NTOFD: s = ">&"; dftfd = 1; break; |
case NTOOV: s = ">|"; dftfd = 1; break; |
case NFROM: s = "<"; dftfd = 0; break; |
case NFROMFD: s = "<&"; dftfd = 0; break; |
case NFROMTO: s = "<>"; dftfd = 0; break; |
default: s = "*error*"; dftfd = 0; break; |
} |
if (np->nfile.fd != dftfd) |
fprintf(fp, "%d", np->nfile.fd); |
fputs(s, fp); |
if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) { |
fprintf(fp, "%d", np->ndup.dupfd); |
} else { |
sharg(np->nfile.fname, fp); |
} |
first = 0; |
} |
} |
static void |
sharg(arg, fp) |
union node *arg; |
FILE *fp; |
{ |
char *p; |
struct nodelist *bqlist; |
int subtype; |
if (arg->type != NARG) { |
printf("<node type %d>\n", arg->type); |
fflush(stdout); |
abort(); |
} |
bqlist = arg->narg.backquote; |
for (p = arg->narg.text ; *p ; p++) { |
switch (*p) { |
case CTLESC: |
putc(*++p, fp); |
break; |
case CTLVAR: |
putc('$', fp); |
putc('{', fp); |
subtype = *++p; |
if (subtype == VSLENGTH) |
putc('#', fp); |
while (*p != '=') |
putc(*p++, fp); |
if (subtype & VSNUL) |
putc(':', fp); |
switch (subtype & VSTYPE) { |
case VSNORMAL: |
putc('}', fp); |
break; |
case VSMINUS: |
putc('-', fp); |
break; |
case VSPLUS: |
putc('+', fp); |
break; |
case VSQUESTION: |
putc('?', fp); |
break; |
case VSASSIGN: |
putc('=', fp); |
break; |
case VSTRIMLEFT: |
putc('#', fp); |
break; |
case VSTRIMLEFTMAX: |
putc('#', fp); |
putc('#', fp); |
break; |
case VSTRIMRIGHT: |
putc('%', fp); |
break; |
case VSTRIMRIGHTMAX: |
putc('%', fp); |
putc('%', fp); |
break; |
case VSLENGTH: |
break; |
default: |
printf("<subtype %d>", subtype); |
} |
break; |
case CTLENDVAR: |
putc('}', fp); |
break; |
case CTLBACKQ: |
case CTLBACKQ|CTLQUOTE: |
putc('$', fp); |
putc('(', fp); |
shtree(bqlist->n, -1, NULL, fp); |
putc(')', fp); |
break; |
default: |
putc(*p, fp); |
break; |
} |
} |
} |
static void |
indent(amount, pfx, fp) |
int amount; |
char *pfx; |
FILE *fp; |
{ |
int i; |
for (i = 0 ; i < amount ; i++) { |
if (pfx && i == amount - 1) |
fputs(pfx, fp); |
putc('\t', fp); |
} |
} |
#endif |
/* |
* Debugging stuff. |
*/ |
FILE *tracefile; |
#if DEBUG == 2 |
int debug = 1; |
#else |
int debug = 0; |
#endif |
#ifdef DEBUG |
void |
trputc(c) |
int c; |
{ |
if (tracefile == NULL) |
return; |
putc(c, tracefile); |
if (c == '\n') |
fflush(tracefile); |
} |
#endif |
void |
#ifdef __STDC__ |
trace(const char *fmt, ...) |
#else |
trace(va_alist) |
va_dcl |
#endif |
{ |
#ifdef DEBUG |
va_list va; |
#ifdef __STDC__ |
va_start(va, fmt); |
#else |
char *fmt; |
va_start(va); |
fmt = va_arg(va, char *); |
#endif |
if (tracefile != NULL) { |
(void) vfprintf(tracefile, fmt, va); |
if (strchr(fmt, '\n')) |
(void) fflush(tracefile); |
} |
va_end(va); |
#endif |
} |
#ifdef DEBUG |
void |
trputs(s) |
const char *s; |
{ |
if (tracefile == NULL) |
return; |
fputs(s, tracefile); |
if (strchr(s, '\n')) |
fflush(tracefile); |
} |
static void |
trstring(s) |
char *s; |
{ |
char *p; |
char c; |
if (tracefile == NULL) |
return; |
putc('"', tracefile); |
for (p = s ; *p ; p++) { |
switch (*p) { |
case '\n': c = 'n'; goto backslash; |
case '\t': c = 't'; goto backslash; |
case '\r': c = 'r'; goto backslash; |
case '"': c = '"'; goto backslash; |
case '\\': c = '\\'; goto backslash; |
case CTLESC: c = 'e'; goto backslash; |
case CTLVAR: c = 'v'; goto backslash; |
case CTLVAR+CTLQUOTE: c = 'V'; goto backslash; |
case CTLBACKQ: c = 'q'; goto backslash; |
case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash; |
backslash: putc('\\', tracefile); |
putc(c, tracefile); |
break; |
default: |
if (*p >= ' ' && *p <= '~') |
putc(*p, tracefile); |
else { |
putc('\\', tracefile); |
putc(*p >> 6 & 03, tracefile); |
putc(*p >> 3 & 07, tracefile); |
putc(*p & 07, tracefile); |
} |
break; |
} |
} |
putc('"', tracefile); |
} |
#endif |
void |
trargs(ap) |
char **ap; |
{ |
#ifdef DEBUG |
if (tracefile == NULL) |
return; |
while (*ap) { |
trstring(*ap++); |
if (*ap) |
putc(' ', tracefile); |
else |
putc('\n', tracefile); |
} |
fflush(tracefile); |
#endif |
} |
#ifdef DEBUG |
void |
opentrace() { |
char s[100]; |
#ifdef O_APPEND |
int flags; |
#endif |
if (!debug) |
return; |
#ifdef not_this_way |
{ |
char *p; |
if ((p = getenv("HOME")) == NULL) { |
if (geteuid() == 0) |
p = "/"; |
else |
p = "/tmp"; |
} |
scopy(p, s); |
strcat(s, "/trace"); |
} |
#else |
scopy("./trace", s); |
#endif /* not_this_way */ |
if ((tracefile = fopen(s, "a")) == NULL) { |
fprintf(stderr, "Can't open %s\n", s); |
return; |
} |
#ifdef O_APPEND |
if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0) |
fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND); |
#endif |
fputs("\nTracing started.\n", tracefile); |
fflush(tracefile); |
} |
#endif /* DEBUG */ |
/branches/dd/uspace/app/ash/mystring.h |
---|
0,0 → 1,49 |
/* $NetBSD: mystring.h,v 1.9 1995/05/11 21:29:42 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)mystring.h 8.2 (Berkeley) 5/4/95 |
*/ |
#include <string.h> |
void scopyn (const char *, char *, int); |
int prefix (const char *, const char *); |
int number (const char *); |
int is_number (const char *); |
#define equal(s1, s2) (strcmp(s1, s2) == 0) |
#define scopy(s1, s2) ((void)strcpy(s2, s1)) |
/branches/dd/uspace/app/ash/show.h |
---|
0,0 → 1,46 |
/* $NetBSD: show.h,v 1.4 1999/10/08 21:10:44 pk Exp $ */ |
/*- |
* Copyright (c) 1995 |
* The Regents of the University of California. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)show.h 1.1 (Berkeley) 5/4/95 |
*/ |
union node; |
void showtree (union node *); |
void trace (const char *, ...); |
void trargs (char **); |
#ifdef DEBUG |
void trputc (int); |
void trputs (const char *); |
void opentrace (void); |
#endif |
/branches/dd/uspace/app/ash/myhistedit.h |
---|
0,0 → 1,50 |
/* $NetBSD: myhistedit.h,v 1.7 1999/07/09 03:05:50 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)myhistedit.h 8.2 (Berkeley) 5/4/95 |
*/ |
#include <histedit.h> |
extern History *hist; |
extern EditLine *el; |
extern int displayhist; |
void histedit (void); |
void sethistsize (const char *); |
void setterm (const char *); |
int histcmd (int, char **); |
int not_fcnumber (char *); |
int str_to_event (const char *, int); |
/branches/dd/uspace/app/ash/arith_lex.l |
---|
0,0 → 1,95 |
%{ |
/* $NetBSD: arith_lex.l,v 1.10 1999/02/05 07:52:52 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)arith_lex.l 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: arith_lex.l,v 1.10 1999/02/05 07:52:52 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <unistd.h> |
#include "arith.h" |
#include "error.h" |
#include "expand.h" |
extern int yylval; |
extern char *arith_buf, *arith_startbuf; |
#undef YY_INPUT |
#define YY_INPUT(buf,result,max) \ |
result = (*buf = *arith_buf++) ? 1 : YY_NULL; |
#define YY_NO_UNPUT |
%} |
%% |
[ \t\n] { ; } |
[0-9]+ { yylval = atol(yytext); return(ARITH_NUM); } |
"(" { return(ARITH_LPAREN); } |
")" { return(ARITH_RPAREN); } |
"||" { return(ARITH_OR); } |
"&&" { return(ARITH_AND); } |
"|" { return(ARITH_BOR); } |
"^" { return(ARITH_BXOR); } |
"&" { return(ARITH_BAND); } |
"==" { return(ARITH_EQ); } |
"!=" { return(ARITH_NE); } |
">" { return(ARITH_GT); } |
">=" { return(ARITH_GE); } |
"<" { return(ARITH_LT); } |
"<=" { return(ARITH_LE); } |
"<<" { return(ARITH_LSHIFT); } |
">>" { return(ARITH_RSHIFT); } |
"*" { return(ARITH_MUL); } |
"/" { return(ARITH_DIV); } |
"%" { return(ARITH_REM); } |
"+" { return(ARITH_ADD); } |
"-" { return(ARITH_SUB); } |
"~" { return(ARITH_BNOT); } |
"!" { return(ARITH_NOT); } |
. { error("arith: syntax error: \"%s\"\n", arith_startbuf); } |
%% |
void |
arith_lex_reset() { |
#ifdef YY_NEW_FILE |
YY_NEW_FILE; |
#endif |
} |
/branches/dd/uspace/app/ash/funcs/dirs |
---|
0,0 → 1,74 |
# $NetBSD: dirs,v 1.7 1995/05/11 21:31:08 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)dirs 8.2 (Berkeley) 5/4/95 |
# pushd, popd, and dirs --- written by Chris Bertin |
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris |
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW |
pushd () { |
SAVE=`pwd` |
if [ "$1" = "" ] |
then if [ "$DSTACK" = "" ] |
then echo "pushd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 || return |
shift 1 |
DSTACK="$*" |
else cd $1 > /dev/null || return |
fi |
DSTACK="$SAVE $DSTACK" |
dirs |
} |
popd () { |
if [ "$DSTACK" = "" ] |
then echo "popd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 |
shift |
DSTACK=$* |
dirs |
} |
dirs () { |
echo "`pwd` $DSTACK" |
return 0 |
} |
/branches/dd/uspace/app/ash/funcs/suspend |
---|
0,0 → 1,42 |
# $NetBSD: suspend,v 1.7 1995/05/11 21:31:17 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)suspend 8.2 (Berkeley) 5/4/95 |
suspend() { |
local - |
set +j |
kill -TSTP 0 |
} |
/branches/dd/uspace/app/ash/funcs/newgrp |
---|
0,0 → 1,38 |
# $NetBSD: newgrp,v 1.7 1995/05/11 21:31:12 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)newgrp 8.2 (Berkeley) 5/4/95 |
newgrp() exec newgrp "$@" |
/branches/dd/uspace/app/ash/funcs/popd |
---|
0,0 → 1,74 |
# $NetBSD: popd,v 1.7 1995/05/11 21:31:13 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)popd 8.2 (Berkeley) 5/4/95 |
# pushd, popd, and dirs --- written by Chris Bertin |
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris |
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW |
pushd () { |
SAVE=`pwd` |
if [ "$1" = "" ] |
then if [ "$DSTACK" = "" ] |
then echo "pushd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 || return |
shift 1 |
DSTACK="$*" |
else cd $1 > /dev/null || return |
fi |
DSTACK="$SAVE $DSTACK" |
dirs |
} |
popd () { |
if [ "$DSTACK" = "" ] |
then echo "popd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 |
shift |
DSTACK=$* |
dirs |
} |
dirs () { |
echo "`pwd` $DSTACK" |
return 0 |
} |
/branches/dd/uspace/app/ash/funcs/pushd |
---|
0,0 → 1,74 |
# $NetBSD: pushd,v 1.7 1995/05/11 21:31:15 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)pushd 8.2 (Berkeley) 5/4/95 |
# pushd, popd, and dirs --- written by Chris Bertin |
# Pixel Computer Inc. ...!wjh12!pixel!pixutl!chris |
# as modified by Patrick Elam of GTRI and Kenneth Almquist at UW |
pushd () { |
SAVE=`pwd` |
if [ "$1" = "" ] |
then if [ "$DSTACK" = "" ] |
then echo "pushd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 || return |
shift 1 |
DSTACK="$*" |
else cd $1 > /dev/null || return |
fi |
DSTACK="$SAVE $DSTACK" |
dirs |
} |
popd () { |
if [ "$DSTACK" = "" ] |
then echo "popd: directory stack empty." |
return 1 |
fi |
set $DSTACK |
cd $1 |
shift |
DSTACK=$* |
dirs |
} |
dirs () { |
echo "`pwd` $DSTACK" |
return 0 |
} |
/branches/dd/uspace/app/ash/funcs/cmv |
---|
0,0 → 1,50 |
# $NetBSD: cmv,v 1.7 1995/05/11 21:31:05 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)cmv 8.2 (Berkeley) 5/4/95 |
# Conditional move--don't replace an existing file. |
cmv() { |
if test $# != 2 |
then echo "cmv: arg count" |
return 2 |
fi |
if test -f "$2" -o -w "$2" |
then echo "$2 exists" |
return 2 |
fi |
/bin/mv "$1" "$2" |
} |
/branches/dd/uspace/app/ash/funcs/login |
---|
0,0 → 1,39 |
# $NetBSD: login,v 1.7 1995/05/11 21:31:11 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)login 8.2 (Berkeley) 5/4/95 |
# replaces the login builtin in the BSD shell |
login () exec login "$@" |
/branches/dd/uspace/app/ash/funcs/kill |
---|
0,0 → 1,50 |
# $NetBSD: kill,v 1.7 1995/05/11 21:31:10 christos Exp $ |
# Copyright (c) 1991, 1993 |
# The Regents of the University of California. All rights reserved. |
# |
# This code is derived from software contributed to Berkeley by |
# Kenneth Almquist. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# 1. Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# 2. Redistributions in binary form must reproduce the above copyright |
# notice, this list of conditions and the following disclaimer in the |
# documentation and/or other materials provided with the distribution. |
# 3. All advertising materials mentioning features or use of this software |
# must display the following acknowledgement: |
# This product includes software developed by the University of |
# California, Berkeley and its contributors. |
# 4. Neither the name of the University nor the names of its contributors |
# may be used to endorse or promote products derived from this software |
# without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
# ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
# SUCH DAMAGE. |
# |
# @(#)kill 8.2 (Berkeley) 5/4/95 |
# Convert job names to process ids and then run /bin/kill. |
kill() { |
local args x |
args= |
for x in "$@" |
do case $x in |
%*) x=`jobid "$x"` ;; |
esac |
args="$args $x" |
done |
/bin/kill $args |
} |
/branches/dd/uspace/app/ash/input.c |
---|
0,0 → 1,531 |
/* $NetBSD: input.c,v 1.34 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)input.c 8.3 (Berkeley) 6/9/95"; |
#else |
__RCSID("$NetBSD: input.c,v 1.34 2000/05/22 10:18:47 elric Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdio.h> /* defines BUFSIZ */ |
#include <fcntl.h> |
#include <errno.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <string.h> |
/* |
* This file implements the input routines used by the parser. |
*/ |
#include "shell.h" |
#include "redir.h" |
#include "syntax.h" |
#include "input.h" |
#include "output.h" |
#include "options.h" |
#include "memalloc.h" |
#include "error.h" |
#include "alias.h" |
#include "parser.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#endif |
#ifdef HETIO |
#include "hetio.h" |
#endif |
#define EOF_NLEFT -99 /* value of parsenleft when EOF pushed back */ |
MKINIT |
struct strpush { |
struct strpush *prev; /* preceding string on stack */ |
char *prevstring; |
int prevnleft; |
int prevlleft; |
struct alias *ap; /* if push was associated with an alias */ |
}; |
/* |
* The parsefile structure pointed to by the global variable parsefile |
* contains information about the current file being read. |
*/ |
MKINIT |
struct parsefile { |
struct parsefile *prev; /* preceding file on stack */ |
int linno; /* current line */ |
int fd; /* file descriptor (or -1 if string) */ |
int nleft; /* number of chars left in this line */ |
int lleft; /* number of chars left in this buffer */ |
char *nextc; /* next char in buffer */ |
char *buf; /* input buffer */ |
struct strpush *strpush; /* for pushing strings at this level */ |
struct strpush basestrpush; /* so pushing one is fast */ |
}; |
int plinno = 1; /* input line number */ |
MKINIT int parsenleft; /* copy of parsefile->nleft */ |
MKINIT int parselleft; /* copy of parsefile->lleft */ |
char *parsenextc; /* copy of parsefile->nextc */ |
MKINIT struct parsefile basepf; /* top level input file */ |
char basebuf[BUFSIZ]; /* buffer for top level input file */ |
struct parsefile *parsefile = &basepf; /* current input file */ |
int init_editline = 0; /* editline library initialized? */ |
int whichprompt; /* 1 == PS1, 2 == PS2 */ |
#ifndef SMALL |
EditLine *el; /* cookie for editline package */ |
#endif |
STATIC void pushfile (void); |
static int preadfd (void); |
#ifdef mkinit |
INCLUDE "input.h" |
INCLUDE "error.h" |
INIT { |
extern char basebuf[]; |
basepf.nextc = basepf.buf = basebuf; |
} |
RESET { |
if (exception != EXSHELLPROC) |
parselleft = parsenleft = 0; /* clear input buffer */ |
popallfiles(); |
} |
SHELLPROC { |
popallfiles(); |
} |
#endif |
/* |
* Read a line from the script. |
*/ |
char * |
pfgets(line, len) |
char *line; |
int len; |
{ |
char *p = line; |
int nleft = len; |
int c; |
while (--nleft > 0) { |
c = pgetc_macro(); |
if (c == PEOF) { |
if (p == line) |
return NULL; |
break; |
} |
*p++ = c; |
if (c == '\n') |
break; |
} |
*p = '\0'; |
return line; |
} |
/* |
* Read a character from the script, returning PEOF on end of file. |
* Nul characters in the input are silently discarded. |
*/ |
int |
pgetc() |
{ |
return pgetc_macro(); |
} |
static int |
preadfd() |
{ |
int nr; |
char *buf = parsefile->buf; |
parsenextc = buf; |
retry: |
#ifndef SMALL |
if (parsefile->fd == 0 && el) { |
const char *rl_cp; |
rl_cp = el_gets(el, &nr); |
if (rl_cp == NULL) |
nr = 0; |
else { |
/* XXX - BUFSIZE should redesign so not necessary */ |
(void) strcpy(buf, rl_cp); |
} |
} else |
#endif |
#ifdef HETIO |
nr = hetio_read_input(parsefile->fd); |
if (nr == -255) |
#endif |
nr = read(parsefile->fd, buf, BUFSIZ - 1); |
if (nr <= 0) { |
if (nr < 0) { |
if (errno == EINTR) |
goto retry; |
if (parsefile->fd == 0 && errno == EWOULDBLOCK) { |
int flags = fcntl(0, F_GETFL, 0); |
if (flags >= 0 && flags & O_NONBLOCK) { |
flags &=~ O_NONBLOCK; |
if (fcntl(0, F_SETFL, flags) >= 0) { |
out2str("sh: turning off NDELAY mode\n"); |
goto retry; |
} |
} |
} |
} |
nr = -1; |
} |
return nr; |
} |
/* |
* Refill the input buffer and return the next input character: |
* |
* 1) If a string was pushed back on the input, pop it; |
* 2) If an EOF was pushed back (parsenleft == EOF_NLEFT) or we are reading |
* from a string so we can't refill the buffer, return EOF. |
* 3) If the is more stuff in this buffer, use it else call read to fill it. |
* 4) Process input up to the next newline, deleting nul characters. |
*/ |
int |
preadbuffer() |
{ |
char *p, *q; |
int more; |
int something; |
char savec; |
if (parsefile->strpush) { |
popstring(); |
if (--parsenleft >= 0) |
return (*parsenextc++); |
} |
if (parsenleft == EOF_NLEFT || parsefile->buf == NULL) |
return PEOF; |
flushout(&output); |
flushout(&errout); |
again: |
if (parselleft <= 0) { |
if ((parselleft = preadfd()) == -1) { |
parselleft = parsenleft = EOF_NLEFT; |
return PEOF; |
} |
} |
q = p = parsenextc; |
/* delete nul characters */ |
something = 0; |
for (more = 1; more;) { |
switch (*p) { |
case '\0': |
p++; /* Skip nul */ |
goto check; |
case '\t': |
case ' ': |
break; |
case '\n': |
parsenleft = q - parsenextc; |
more = 0; /* Stop processing here */ |
break; |
default: |
something = 1; |
break; |
} |
*q++ = *p++; |
check: |
if (--parselleft <= 0) { |
parsenleft = q - parsenextc - 1; |
if (parsenleft < 0) |
goto again; |
*q = '\0'; |
more = 0; |
} |
} |
savec = *q; |
*q = '\0'; |
#ifndef SMALL |
if (parsefile->fd == 0 && hist && something) { |
HistEvent he; |
INTOFF; |
history(hist, &he, whichprompt == 1? H_ENTER : H_APPEND, |
parsenextc); |
INTON; |
} |
#endif |
if (vflag) { |
out2str(parsenextc); |
flushout(out2); |
} |
*q = savec; |
return *parsenextc++; |
} |
/* |
* Undo the last call to pgetc. Only one character may be pushed back. |
* PEOF may be pushed back. |
*/ |
void |
pungetc() { |
parsenleft++; |
parsenextc--; |
} |
/* |
* Push a string back onto the input at this current parsefile level. |
* We handle aliases this way. |
*/ |
void |
pushstring(s, len, ap) |
char *s; |
int len; |
void *ap; |
{ |
struct strpush *sp; |
INTOFF; |
/*dprintf("*** calling pushstring: %s, %d\n", s, len);*/ |
if (parsefile->strpush) { |
sp = ckmalloc(sizeof (struct strpush)); |
sp->prev = parsefile->strpush; |
parsefile->strpush = sp; |
} else |
sp = parsefile->strpush = &(parsefile->basestrpush); |
sp->prevstring = parsenextc; |
sp->prevnleft = parsenleft; |
sp->prevlleft = parselleft; |
sp->ap = (struct alias *)ap; |
if (ap) |
((struct alias *)ap)->flag |= ALIASINUSE; |
parsenextc = s; |
parsenleft = len; |
INTON; |
} |
void |
popstring() |
{ |
struct strpush *sp = parsefile->strpush; |
INTOFF; |
parsenextc = sp->prevstring; |
parsenleft = sp->prevnleft; |
parselleft = sp->prevlleft; |
/*dprintf("*** calling popstring: restoring to '%s'\n", parsenextc);*/ |
if (sp->ap) |
sp->ap->flag &= ~ALIASINUSE; |
parsefile->strpush = sp->prev; |
if (sp != &(parsefile->basestrpush)) |
ckfree(sp); |
INTON; |
} |
/* |
* Set the input to take input from a file. If push is set, push the |
* old input onto the stack first. |
*/ |
void |
setinputfile(fname, push) |
const char *fname; |
int push; |
{ |
int fd; |
int fd2; |
INTOFF; |
if ((fd = open(fname, O_RDONLY)) < 0) |
error("Can't open %s", fname); |
if (fd < 10) { |
fd2 = copyfd(fd, 10); |
close(fd); |
if (fd2 < 0) |
error("Out of file descriptors"); |
fd = fd2; |
} |
setinputfd(fd, push); |
INTON; |
} |
/* |
* Like setinputfile, but takes an open file descriptor. Call this with |
* interrupts off. |
*/ |
void |
setinputfd(fd, push) |
int fd, push; |
{ |
(void) fcntl(fd, F_SETFD, FD_CLOEXEC); |
if (push) { |
pushfile(); |
parsefile->buf = ckmalloc(BUFSIZ); |
} |
if (parsefile->fd > 0) |
close(parsefile->fd); |
parsefile->fd = fd; |
if (parsefile->buf == NULL) |
parsefile->buf = ckmalloc(BUFSIZ); |
parselleft = parsenleft = 0; |
plinno = 1; |
} |
/* |
* Like setinputfile, but takes input from a string. |
*/ |
void |
setinputstring(string, push) |
char *string; |
int push; |
{ |
INTOFF; |
if (push) |
pushfile(); |
parsenextc = string; |
parselleft = parsenleft = strlen(string); |
parsefile->buf = NULL; |
plinno = 1; |
INTON; |
} |
/* |
* To handle the "." command, a stack of input files is used. Pushfile |
* adds a new entry to the stack and popfile restores the previous level. |
*/ |
STATIC void |
pushfile() { |
struct parsefile *pf; |
parsefile->nleft = parsenleft; |
parsefile->lleft = parselleft; |
parsefile->nextc = parsenextc; |
parsefile->linno = plinno; |
pf = (struct parsefile *)ckmalloc(sizeof (struct parsefile)); |
pf->prev = parsefile; |
pf->fd = -1; |
pf->strpush = NULL; |
pf->basestrpush.prev = NULL; |
parsefile = pf; |
} |
void |
popfile() { |
struct parsefile *pf = parsefile; |
INTOFF; |
if (pf->fd >= 0) |
close(pf->fd); |
if (pf->buf) |
ckfree(pf->buf); |
while (pf->strpush) |
popstring(); |
parsefile = pf->prev; |
ckfree(pf); |
parsenleft = parsefile->nleft; |
parselleft = parsefile->lleft; |
parsenextc = parsefile->nextc; |
plinno = parsefile->linno; |
INTON; |
} |
/* |
* Return to top level. |
*/ |
void |
popallfiles() { |
while (parsefile != &basepf) |
popfile(); |
} |
/* |
* Close the file(s) that the shell is reading commands from. Called |
* after a fork is done. |
*/ |
void |
closescript() { |
popallfiles(); |
if (parsefile->fd > 0) { |
close(parsefile->fd); |
parsefile->fd = 0; |
} |
} |
/branches/dd/uspace/app/ash/input.h |
---|
0,0 → 1,66 |
/* $NetBSD: input.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)input.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* PEOF (the end of file marker) is defined in syntax.h */ |
/* |
* The input line number. Input.c just defines this variable, and saves |
* and restores it when files are pushed and popped. The user of this |
* package must set its value. |
*/ |
extern int plinno; |
extern int parsenleft; /* number of characters left in input buffer */ |
extern char *parsenextc; /* next character in input buffer */ |
extern int init_editline; /* 0 == not setup, 1 == OK, -1 == failed */ |
char *pfgets (char *, int); |
int pgetc (void); |
int preadbuffer (void); |
void pungetc (void); |
void pushstring (char *, int, void *); |
void popstring (void); |
void setinputfile (const char *, int); |
void setinputfd (int, int); |
void setinputstring (char *, int); |
void popfile (void); |
void popallfiles (void); |
void closescript (void); |
#define pgetc_macro() (--parsenleft >= 0? *parsenextc++ : preadbuffer()) |
/branches/dd/uspace/app/ash/redir.c |
---|
0,0 → 1,492 |
/* $NetBSD: redir.c,v 1.22 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)redir.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: redir.c,v 1.22 2000/05/22 10:18:47 elric Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/stat.h> |
#include <sys/types.h> |
#include <sys/param.h> /* PIPE_BUF */ |
#include <signal.h> |
#include <string.h> |
#include <fcntl.h> |
#include <errno.h> |
#include <unistd.h> |
#include <stdlib.h> |
/* |
* Code for dealing with input/output redirection. |
*/ |
#include "shell.h" |
#include "nodes.h" |
#include "jobs.h" |
#include "expand.h" |
#include "redir.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "options.h" |
#define EMPTY -2 /* marks an unused slot in redirtab */ |
#ifndef PIPE_BUF |
# define PIPESIZE 4096 /* amount of buffering in a pipe */ |
#else |
# define PIPESIZE PIPE_BUF |
#endif |
MKINIT |
struct redirtab { |
struct redirtab *next; |
short renamed[10]; |
}; |
MKINIT struct redirtab *redirlist; |
/* |
* We keep track of whether or not fd0 has been redirected. This is for |
* background commands, where we want to redirect fd0 to /dev/null only |
* if it hasn't already been redirected. |
*/ |
int fd0_redirected = 0; |
/* |
* We also keep track of where fd2 goes. |
*/ |
int fd2 = 2; |
STATIC int openredirect (union node *); |
STATIC void dupredirect (union node *, int, char[10 ]); |
STATIC int openhere (union node *); |
STATIC int noclobberopen (const char *); |
/* |
* Process a list of redirection commands. If the REDIR_PUSH flag is set, |
* old file descriptors are stashed away so that the redirection can be |
* undone by calling popredir. If the REDIR_BACKQ flag is set, then the |
* standard output, and the standard error if it becomes a duplicate of |
* stdout, is saved in memory. |
*/ |
void |
redirect(redir, flags) |
union node *redir; |
int flags; |
{ |
union node *n; |
struct redirtab *sv = NULL; |
int i; |
int fd; |
int newfd; |
int try; |
char memory[10]; /* file descriptors to write to memory */ |
for (i = 10 ; --i >= 0 ; ) |
memory[i] = 0; |
memory[1] = flags & REDIR_BACKQ; |
if (flags & REDIR_PUSH) { |
sv = ckmalloc(sizeof (struct redirtab)); |
for (i = 0 ; i < 10 ; i++) |
sv->renamed[i] = EMPTY; |
sv->next = redirlist; |
redirlist = sv; |
} |
for (n = redir ; n ; n = n->nfile.next) { |
fd = n->nfile.fd; |
try = 0; |
if ((n->nfile.type == NTOFD || n->nfile.type == NFROMFD) && |
n->ndup.dupfd == fd) |
continue; /* redirect from/to same file descriptor */ |
INTOFF; |
newfd = openredirect(n); |
if (((flags & REDIR_PUSH) && sv->renamed[fd] == EMPTY) || |
(fd == fd2)) { |
if (newfd == fd) { |
try++; |
} else if ((i = fcntl(fd, F_DUPFD, 10)) == -1) { |
switch (errno) { |
case EBADF: |
if (!try) { |
dupredirect(n, newfd, memory); |
try++; |
break; |
} |
/* FALLTHROUGH*/ |
default: |
if (newfd >= 0) { |
close(newfd); |
} |
INTON; |
error("%d: %s", fd, strerror(errno)); |
/* NOTREACHED */ |
} |
} |
if (!try) { |
close(fd); |
if (flags & REDIR_PUSH) { |
sv->renamed[fd] = i; |
} |
if (fd == fd2) { |
fd2 = i; |
} |
} |
} else if (fd != newfd) { |
close(fd); |
} |
if (fd == 0) |
fd0_redirected++; |
if (!try) |
dupredirect(n, newfd, memory); |
INTON; |
} |
if (memory[1]) |
out1 = &memout; |
if (memory[2]) |
out2 = &memout; |
} |
STATIC int |
openredirect(redir) |
union node *redir; |
{ |
char *fname; |
int f; |
switch (redir->nfile.type) { |
case NFROM: |
fname = redir->nfile.expfname; |
if ((f = open(fname, O_RDONLY)) < 0) |
goto eopen; |
break; |
case NFROMTO: |
fname = redir->nfile.expfname; |
if ((f = open(fname, O_RDWR|O_CREAT|O_TRUNC, 0666)) < 0) |
goto ecreate; |
break; |
case NTO: |
/* Take care of noclobber mode. */ |
if (Cflag) { |
fname = redir->nfile.expfname; |
if ((f = noclobberopen(fname)) < 0) |
goto ecreate; |
break; |
} |
case NTOOV: |
fname = redir->nfile.expfname; |
#ifdef O_CREAT |
if ((f = open(fname, O_WRONLY|O_CREAT|O_TRUNC, 0666)) < 0) |
goto ecreate; |
#else |
if ((f = creat(fname, 0666)) < 0) |
goto ecreate; |
#endif |
break; |
case NAPPEND: |
fname = redir->nfile.expfname; |
#ifdef O_APPEND |
if ((f = open(fname, O_WRONLY|O_CREAT|O_APPEND, 0666)) < 0) |
goto ecreate; |
#else |
if ((f = open(fname, O_WRONLY)) < 0 |
&& (f = creat(fname, 0666)) < 0) |
goto ecreate; |
lseek(f, (off_t)0, 2); |
#endif |
break; |
case NTOFD: |
case NFROMFD: |
f = -1; |
break; |
case NHERE: |
case NXHERE: |
f = openhere(redir); |
break; |
default: |
abort(); |
} |
return f; |
ecreate: |
error("cannot create %s: %s", fname, errmsg(errno, E_CREAT)); |
eopen: |
error("cannot open %s: %s", fname, errmsg(errno, E_OPEN)); |
} |
STATIC void |
dupredirect(redir, f, memory) |
union node *redir; |
int f; |
char memory[10]; |
{ |
int fd = redir->nfile.fd; |
memory[fd] = 0; |
if (redir->nfile.type == NTOFD || redir->nfile.type == NFROMFD) { |
if (redir->ndup.dupfd >= 0) { /* if not ">&-" */ |
if (memory[redir->ndup.dupfd]) |
memory[fd] = 1; |
else |
copyfd(redir->ndup.dupfd, fd); |
} |
return; |
} |
if (f != fd) { |
copyfd(f, fd); |
close(f); |
} |
return; |
} |
/* |
* Handle here documents. Normally we fork off a process to write the |
* data to a pipe. If the document is short, we can stuff the data in |
* the pipe without forking. |
*/ |
STATIC int |
openhere(redir) |
union node *redir; |
{ |
int pip[2]; |
int len = 0; |
if (pipe(pip) < 0) |
error("Pipe call failed"); |
if (redir->type == NHERE) { |
len = strlen(redir->nhere.doc->narg.text); |
if (len <= PIPESIZE) { |
xwrite(pip[1], redir->nhere.doc->narg.text, len); |
goto out; |
} |
} |
if (forkshell((struct job *)NULL, (union node *)NULL, FORK_NOJOB) == 0) { |
close(pip[0]); |
signal(SIGINT, SIG_IGN); |
signal(SIGQUIT, SIG_IGN); |
signal(SIGHUP, SIG_IGN); |
#ifdef SIGTSTP |
signal(SIGTSTP, SIG_IGN); |
#endif |
signal(SIGPIPE, SIG_DFL); |
if (redir->type == NHERE) |
xwrite(pip[1], redir->nhere.doc->narg.text, len); |
else |
expandhere(redir->nhere.doc, pip[1]); |
_exit(0); |
} |
out: |
close(pip[1]); |
return pip[0]; |
} |
/* |
* Undo the effects of the last redirection. |
*/ |
void |
popredir() { |
struct redirtab *rp = redirlist; |
int i; |
INTOFF; |
for (i = 0 ; i < 10 ; i++) { |
if (rp->renamed[i] != EMPTY) { |
if (i == 0) |
fd0_redirected--; |
close(i); |
if (rp->renamed[i] >= 0) { |
copyfd(rp->renamed[i], i); |
close(rp->renamed[i]); |
} |
if (rp->renamed[i] == fd2) { |
fd2 = i; |
} |
} |
} |
redirlist = rp->next; |
ckfree(rp); |
INTON; |
} |
/* |
* Undo all redirections. Called on error or interrupt. |
*/ |
#ifdef mkinit |
INCLUDE "redir.h" |
RESET { |
while (redirlist) |
popredir(); |
} |
SHELLPROC { |
clearredir(); |
} |
#endif |
/* Return true if fd 0 has already been redirected at least once. */ |
int |
fd0_redirected_p () { |
return fd0_redirected != 0; |
} |
/* |
* Discard all saved file descriptors. |
*/ |
void |
clearredir() { |
struct redirtab *rp; |
int i; |
for (rp = redirlist ; rp ; rp = rp->next) { |
for (i = 0 ; i < 10 ; i++) { |
if (rp->renamed[i] >= 0) { |
close(rp->renamed[i]); |
if (rp->renamed[i] == fd2) { |
fd2 = -1; |
} |
} |
rp->renamed[i] = EMPTY; |
} |
} |
} |
/* |
* Copy a file descriptor to be >= to. Returns -1 |
* if the source file descriptor is closed, EMPTY if there are no unused |
* file descriptors left. |
*/ |
int |
copyfd(from, to) |
int from; |
int to; |
{ |
int newfd; |
newfd = fcntl(from, F_DUPFD, to); |
if (newfd < 0) { |
if (errno == EMFILE) |
return EMPTY; |
else |
error("%d: %s", from, strerror(errno)); |
} |
return newfd; |
} |
/* |
* Open a file in noclobber mode. |
* The code was copied from bash. |
*/ |
int |
noclobberopen(fname) |
const char *fname; |
{ |
int r, fd; |
struct stat finfo, finfo2; |
/* |
* If the file exists and is a regular file, return an error |
* immediately. |
*/ |
r = stat(fname, &finfo); |
if (r == 0 && S_ISREG(finfo.st_mode)) { |
errno = EEXIST; |
return -1; |
} |
/* |
* If the file was not present (r != 0), make sure we open it |
* exclusively so that if it is created before we open it, our open |
* will fail. Make sure that we do not truncate an existing file. |
* Note that we don't turn on O_EXCL unless the stat failed -- if the |
* file was not a regular file, we leave O_EXCL off. |
*/ |
if (r != 0) |
return open(fname, O_WRONLY|O_CREAT|O_EXCL, 0666); |
fd = open(fname, O_WRONLY|O_CREAT, 0666); |
/* If the open failed, return the file descriptor right away. */ |
if (fd < 0) |
return fd; |
/* |
* OK, the open succeeded, but the file may have been changed from a |
* non-regular file to a regular file between the stat and the open. |
* We are assuming that the O_EXCL open handles the case where FILENAME |
* did not exist and is symlinked to an existing file between the stat |
* and open. |
*/ |
/* |
* If we can open it and fstat the file descriptor, and neither check |
* revealed that it was a regular file, and the file has not been |
* replaced, return the file descriptor. |
*/ |
if (fstat(fd, &finfo2) == 0 && !S_ISREG(finfo2.st_mode) && |
finfo.st_dev == finfo2.st_dev && finfo.st_ino == finfo2.st_ino) |
return fd; |
/* The file has been replaced. badness. */ |
close(fd); |
errno = EEXIST; |
return -1; |
} |
/branches/dd/uspace/app/ash/trap.c |
---|
0,0 → 1,401 |
/* $NetBSD: trap.c,v 1.24 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)trap.c 8.5 (Berkeley) 6/5/95"; |
#else |
__RCSID("$NetBSD: trap.c,v 1.24 2000/05/22 10:18:47 elric Exp $"); |
#endif |
#endif /* not lint */ |
#include <signal.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include "shell.h" |
#include "main.h" |
#include "nodes.h" /* for other headers */ |
#include "eval.h" |
#include "jobs.h" |
#include "show.h" |
#include "options.h" |
#include "syntax.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "trap.h" |
#include "mystring.h" |
#include "mail.h" |
#ifdef HETIO |
#include "hetio.h" |
#endif |
/* |
* Sigmode records the current value of the signal handlers for the various |
* modes. A value of zero means that the current handler is not known. |
* S_HARD_IGN indicates that the signal was ignored on entry to the shell, |
*/ |
#define S_DFL 1 /* default signal handling (SIG_DFL) */ |
#define S_CATCH 2 /* signal is caught */ |
#define S_IGN 3 /* signal is ignored (SIG_IGN) */ |
#define S_HARD_IGN 4 /* signal is ignored permenantly */ |
#define S_RESET 5 /* temporary - to reset a hard ignored sig */ |
extern char nullstr[1]; /* null string */ |
char *trap[NSIG+1]; /* trap handler commands */ |
MKINIT char sigmode[NSIG]; /* current value of signal */ |
char gotsig[NSIG]; /* indicates specified signal received */ |
int pendingsigs; /* indicates some signal received */ |
extern char *signal_names[]; |
/* |
* The trap builtin. |
*/ |
int |
trapcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char *action; |
char **ap; |
int signo; |
if (argc <= 1) { |
for (signo = 0 ; signo <= NSIG ; signo++) { |
if (trap[signo] != NULL) |
out1fmt("%d: %s\n", signo, trap[signo]); |
} |
return 0; |
} |
ap = argv + 1; |
if (argc == 2) |
action = NULL; |
else |
action = *ap++; |
while (*ap) { |
if ((signo = decode_signal(*ap)) < 0) |
error("%s: bad trap", *ap); |
INTOFF; |
if (action) { |
if (action[0] == '-' && action[1] == '\0') |
action = NULL; |
else |
action = savestr(action); |
} |
if (trap[signo]) |
ckfree(trap[signo]); |
trap[signo] = action; |
if (signo != 0) |
setsignal(signo); |
INTON; |
ap++; |
} |
return 0; |
} |
/* |
* Clear traps on a fork. |
*/ |
void |
clear_traps() { |
char **tp; |
for (tp = trap ; tp <= &trap[NSIG] ; tp++) { |
if (*tp && **tp) { /* trap not NULL or SIG_IGN */ |
INTOFF; |
ckfree(*tp); |
*tp = NULL; |
if (tp != &trap[0]) |
setsignal(tp - trap); |
INTON; |
} |
} |
} |
/* |
* Set the signal handler for the specified signal. The routine figures |
* out what it should be set to. |
*/ |
void |
setsignal(signo) |
int signo; |
{ |
int action; |
char *t; |
struct sigaction act; |
if ((t = trap[signo]) == NULL) |
action = S_DFL; |
else if (*t != '\0') |
action = S_CATCH; |
else |
action = S_IGN; |
if (rootshell && action == S_DFL) { |
switch (signo) { |
case SIGINT: |
if (iflag || minusc || sflag == 0) |
action = S_CATCH; |
break; |
case SIGQUIT: |
#ifdef DEBUG |
{ |
extern int debug; |
if (debug) |
break; |
} |
#endif |
/* FALLTHROUGH */ |
case SIGTERM: |
if (iflag) |
action = S_IGN; |
break; |
#if JOBS |
case SIGTSTP: |
case SIGTTOU: |
if (mflag) |
action = S_IGN; |
break; |
#endif |
} |
} |
t = &sigmode[signo - 1]; |
if (*t == 0) { |
/* |
* current setting unknown |
*/ |
if (sigaction(signo, 0, &act) == -1) { |
/* |
* Pretend it worked; maybe we should give a warning |
* here, but other shells don't. We don't alter |
* sigmode, so that we retry every time. |
*/ |
return; |
} |
if (act.sa_handler == SIG_IGN) { |
if (mflag && (signo == SIGTSTP || |
signo == SIGTTIN || signo == SIGTTOU)) { |
*t = S_IGN; /* don't hard ignore these */ |
} else |
*t = S_HARD_IGN; |
} else { |
*t = S_RESET; /* force to be set */ |
} |
} |
if (*t == S_HARD_IGN || *t == action) |
return; |
switch (action) { |
case S_CATCH: |
act.sa_handler = onsig; |
break; |
case S_IGN: |
act.sa_handler = SIG_IGN; |
break; |
default: |
act.sa_handler = SIG_DFL; |
} |
*t = action; |
act.sa_flags = 0; |
sigemptyset(&act.sa_mask); |
sigaction(signo, &act, 0); |
} |
/* |
* Ignore a signal. |
*/ |
void |
ignoresig(signo) |
int signo; |
{ |
if (sigmode[signo - 1] != S_IGN && sigmode[signo - 1] != S_HARD_IGN) { |
signal(signo, SIG_IGN); |
} |
sigmode[signo - 1] = S_HARD_IGN; |
} |
#ifdef mkinit |
INCLUDE <signal.h> |
INCLUDE "trap.h" |
SHELLPROC { |
char *sm; |
clear_traps(); |
for (sm = sigmode ; sm < sigmode + NSIG ; sm++) { |
if (*sm == S_IGN) |
*sm = S_HARD_IGN; |
} |
} |
#endif |
/* |
* Signal handler. |
*/ |
void |
onsig(signo) |
int signo; |
{ |
signal(signo, onsig); |
if (signo == SIGINT && trap[SIGINT] == NULL) { |
onint(); |
return; |
} |
gotsig[signo - 1] = 1; |
pendingsigs++; |
} |
/* |
* Called to execute a trap. Perhaps we should avoid entering new trap |
* handlers while we are executing a trap handler. |
*/ |
void |
dotrap() { |
int i; |
int savestatus; |
for (;;) { |
for (i = 1 ; ; i++) { |
if (gotsig[i - 1]) |
break; |
if (i >= NSIG) |
goto done; |
} |
gotsig[i - 1] = 0; |
savestatus=exitstatus; |
evalstring(trap[i], 0); |
exitstatus=savestatus; |
} |
done: |
pendingsigs = 0; |
} |
/* |
* Controls whether the shell is interactive or not. |
*/ |
void |
setinteractive(on) |
int on; |
{ |
static int is_interactive; |
if (on == is_interactive) |
return; |
setsignal(SIGINT); |
setsignal(SIGQUIT); |
setsignal(SIGTERM); |
chkmail(1); |
is_interactive = on; |
} |
/* |
* Called to exit the shell. |
*/ |
void |
exitshell(status) |
int status; |
{ |
struct jmploc loc1, loc2; |
char *p; |
TRACE(("exitshell(%d) pid=%d\n", status, getpid())); |
#ifdef HETIO |
hetio_reset_term(); |
#endif |
if (setjmp(loc1.loc)) { |
goto l1; |
} |
if (setjmp(loc2.loc)) { |
goto l2; |
} |
handler = &loc1; |
if ((p = trap[0]) != NULL && *p != '\0') { |
trap[0] = NULL; |
evalstring(p, 0); |
} |
l1: handler = &loc2; /* probably unnecessary */ |
flushall(); |
#if JOBS |
setjobctl(0); |
#endif |
l2: _exit(status); |
/* NOTREACHED */ |
} |
int decode_signal(const char *string) |
{ |
int signo; |
if (is_number(string)) return atoi(string); |
for (signo=0; signo < NSIG; signo++) |
if (strcasecmp(string, signal_names[signo]) == 0 || |
strcasecmp(string, &(signal_names[signo])[3]) == 0) |
return signo; |
return -1; |
} |
/branches/dd/uspace/app/ash/arith.c |
---|
0,0 → 1,1907 |
/* A Bison parser, made by GNU Bison 2.3. */ |
/* Skeleton implementation for Bison's Yacc-like parsers in C |
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 |
Free Software Foundation, Inc. |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2, or (at your option) |
any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, |
Boston, MA 02110-1301, USA. */ |
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
/* C LALR(1) parser skeleton written by Richard Stallman, by |
simplifying the original so-called "semantic" parser. */ |
/* All symbols defined below should begin with yy or YY, to avoid |
infringing on user name space. This should be done even for local |
variables, as they might otherwise be expanded by user macros. |
There are some unavoidable exceptions within include files to |
define necessary library symbols; they are noted "INFRINGES ON |
USER NAME SPACE" below. */ |
/* Identify Bison output. */ |
#define YYBISON 1 |
/* Bison version. */ |
#define YYBISON_VERSION "2.3" |
/* Skeleton name. */ |
#define YYSKELETON_NAME "yacc.c" |
/* Pure parsers. */ |
#define YYPURE 0 |
/* Using locations. */ |
#define YYLSP_NEEDED 0 |
/* Tokens. */ |
#ifndef YYTOKENTYPE |
# define YYTOKENTYPE |
/* Put the tokens into the symbol table, so that GDB and other debuggers |
know about them. */ |
enum yytokentype { |
ARITH_NUM = 258, |
ARITH_LPAREN = 259, |
ARITH_RPAREN = 260, |
ARITH_OR = 261, |
ARITH_AND = 262, |
ARITH_BOR = 263, |
ARITH_BXOR = 264, |
ARITH_BAND = 265, |
ARITH_NE = 266, |
ARITH_EQ = 267, |
ARITH_LE = 268, |
ARITH_GE = 269, |
ARITH_GT = 270, |
ARITH_LT = 271, |
ARITH_RSHIFT = 272, |
ARITH_LSHIFT = 273, |
ARITH_SUB = 274, |
ARITH_ADD = 275, |
ARITH_REM = 276, |
ARITH_DIV = 277, |
ARITH_MUL = 278, |
ARITH_BNOT = 279, |
ARITH_NOT = 280, |
ARITH_UNARYPLUS = 281, |
ARITH_UNARYMINUS = 282 |
}; |
#endif |
/* Tokens. */ |
#define ARITH_NUM 258 |
#define ARITH_LPAREN 259 |
#define ARITH_RPAREN 260 |
#define ARITH_OR 261 |
#define ARITH_AND 262 |
#define ARITH_BOR 263 |
#define ARITH_BXOR 264 |
#define ARITH_BAND 265 |
#define ARITH_NE 266 |
#define ARITH_EQ 267 |
#define ARITH_LE 268 |
#define ARITH_GE 269 |
#define ARITH_GT 270 |
#define ARITH_LT 271 |
#define ARITH_RSHIFT 272 |
#define ARITH_LSHIFT 273 |
#define ARITH_SUB 274 |
#define ARITH_ADD 275 |
#define ARITH_REM 276 |
#define ARITH_DIV 277 |
#define ARITH_MUL 278 |
#define ARITH_BNOT 279 |
#define ARITH_NOT 280 |
#define ARITH_UNARYPLUS 281 |
#define ARITH_UNARYMINUS 282 |
/* Copy the first part of user declarations. */ |
#line 1 "arith.y" |
/* $NetBSD: arith.y,v 1.13 1999/07/09 03:05:49 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: arith.y,v 1.13 1999/07/09 03:05:49 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdlib.h> |
#include "expand.h" |
#include "shell.h" |
#include "error.h" |
#include "output.h" |
#include "memalloc.h" |
const char *arith_buf, *arith_startbuf; |
void yyerror (const char *); |
int yyparse (void); |
#ifdef TESTARITH |
int main (int , char *[]); |
int error (char *); |
#endif |
int |
arith(s) |
const char *s; |
{ |
long result; |
arith_buf = arith_startbuf = s; |
INTOFF; |
result = yyparse(); |
arith_lex_reset(); /* reprime lex */ |
INTON; |
return (result); |
} |
/* |
* The exp(1) builtin. |
*/ |
int |
expcmd(argc, argv) |
int argc; |
char **argv; |
{ |
const char *p; |
char *concat; |
char **ap; |
long i; |
if (argc > 1) { |
p = argv[1]; |
if (argc > 2) { |
/* |
* concatenate arguments |
*/ |
STARTSTACKSTR(concat); |
ap = argv + 2; |
for (;;) { |
while (*p) |
STPUTC(*p++, concat); |
if ((p = *ap++) == NULL) |
break; |
STPUTC(' ', concat); |
} |
STPUTC('\0', concat); |
p = grabstackstr(concat); |
} |
} else |
p = ""; |
i = arith(p); |
out1fmt("%ld\n", i); |
return (! i); |
} |
/*************************/ |
#ifdef TEST_ARITH |
#include <stdio.h> |
main(argc, argv) |
char *argv[]; |
{ |
printf("%d\n", exp(argv[1])); |
} |
error(s) |
char *s; |
{ |
fprintf(stderr, "exp: %s\n", s); |
exit(1); |
} |
#endif |
/* Enabling traces. */ |
#ifndef YYDEBUG |
# define YYDEBUG 0 |
#endif |
/* Enabling verbose error messages. */ |
#ifdef YYERROR_VERBOSE |
# undef YYERROR_VERBOSE |
# define YYERROR_VERBOSE 1 |
#else |
# define YYERROR_VERBOSE 0 |
#endif |
/* Enabling the token table. */ |
#ifndef YYTOKEN_TABLE |
# define YYTOKEN_TABLE 0 |
#endif |
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED |
typedef int YYSTYPE; |
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ |
# define YYSTYPE_IS_DECLARED 1 |
# define YYSTYPE_IS_TRIVIAL 1 |
#endif |
/* Copy the second part of user declarations. */ |
/* Line 216 of yacc.c. */ |
#line 298 "y.tab.c" |
#ifdef short |
# undef short |
#endif |
#ifdef YYTYPE_UINT8 |
typedef YYTYPE_UINT8 yytype_uint8; |
#else |
typedef unsigned char yytype_uint8; |
#endif |
#ifdef YYTYPE_INT8 |
typedef YYTYPE_INT8 yytype_int8; |
#elif (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
typedef signed char yytype_int8; |
#else |
typedef short int yytype_int8; |
#endif |
#ifdef YYTYPE_UINT16 |
typedef YYTYPE_UINT16 yytype_uint16; |
#else |
typedef unsigned short int yytype_uint16; |
#endif |
#ifdef YYTYPE_INT16 |
typedef YYTYPE_INT16 yytype_int16; |
#else |
typedef short int yytype_int16; |
#endif |
#ifndef YYSIZE_T |
# ifdef __SIZE_TYPE__ |
# define YYSIZE_T __SIZE_TYPE__ |
# elif defined size_t |
# define YYSIZE_T size_t |
# elif ! defined YYSIZE_T && (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
# include <stddef.h> /* INFRINGES ON USER NAME SPACE */ |
# define YYSIZE_T size_t |
# else |
# define YYSIZE_T unsigned int |
# endif |
#endif |
#define YYSIZE_MAXIMUM ((YYSIZE_T) -1) |
#ifndef YY_ |
# if YYENABLE_NLS |
# if ENABLE_NLS |
# include <libintl.h> /* INFRINGES ON USER NAME SPACE */ |
# define YY_(msgid) dgettext ("bison-runtime", msgid) |
# endif |
# endif |
# ifndef YY_ |
# define YY_(msgid) msgid |
# endif |
#endif |
/* Suppress unused-variable warnings by "using" E. */ |
#if ! defined lint || defined __GNUC__ |
# define YYUSE(e) ((void) (e)) |
#else |
# define YYUSE(e) /* empty */ |
#endif |
/* Identity function, used to suppress warnings about constant conditions. */ |
#ifndef lint |
# define YYID(n) (n) |
#else |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static int |
YYID (int i) |
#else |
static int |
YYID (i) |
int i; |
#endif |
{ |
return i; |
} |
#endif |
#if ! defined yyoverflow || YYERROR_VERBOSE |
/* The parser invokes alloca or malloc; define the necessary symbols. */ |
# ifdef YYSTACK_USE_ALLOCA |
# if YYSTACK_USE_ALLOCA |
# ifdef __GNUC__ |
# define YYSTACK_ALLOC __builtin_alloca |
# elif defined __BUILTIN_VA_ARG_INCR |
# include <alloca.h> /* INFRINGES ON USER NAME SPACE */ |
# elif defined _AIX |
# define YYSTACK_ALLOC __alloca |
# elif defined _MSC_VER |
# include <malloc.h> /* INFRINGES ON USER NAME SPACE */ |
# define alloca _alloca |
# else |
# define YYSTACK_ALLOC alloca |
# if ! defined _ALLOCA_H && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ |
# ifndef _STDLIB_H |
# define _STDLIB_H 1 |
# endif |
# endif |
# endif |
# endif |
# endif |
# ifdef YYSTACK_ALLOC |
/* Pacify GCC's `empty if-body' warning. */ |
# define YYSTACK_FREE(Ptr) do { /* empty */; } while (YYID (0)) |
# ifndef YYSTACK_ALLOC_MAXIMUM |
/* The OS might guarantee only one guard page at the bottom of the stack, |
and a page size can be as small as 4096 bytes. So we cannot safely |
invoke alloca (N) if N exceeds 4096. Use a slightly smaller number |
to allow for a few compiler-allocated temporary stack slots. */ |
# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */ |
# endif |
# else |
# define YYSTACK_ALLOC YYMALLOC |
# define YYSTACK_FREE YYFREE |
# ifndef YYSTACK_ALLOC_MAXIMUM |
# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM |
# endif |
# if (defined __cplusplus && ! defined _STDLIB_H \ |
&& ! ((defined YYMALLOC || defined malloc) \ |
&& (defined YYFREE || defined free))) |
# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */ |
# ifndef _STDLIB_H |
# define _STDLIB_H 1 |
# endif |
# endif |
# ifndef YYMALLOC |
# define YYMALLOC malloc |
# if ! defined malloc && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */ |
# endif |
# endif |
# ifndef YYFREE |
# define YYFREE free |
# if ! defined free && ! defined _STDLIB_H && (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
void free (void *); /* INFRINGES ON USER NAME SPACE */ |
# endif |
# endif |
# endif |
#endif /* ! defined yyoverflow || YYERROR_VERBOSE */ |
#if (! defined yyoverflow \ |
&& (! defined __cplusplus \ |
|| (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL))) |
/* A type that is properly aligned for any stack member. */ |
union yyalloc |
{ |
yytype_int16 yyss; |
YYSTYPE yyvs; |
}; |
/* The size of the maximum gap between one aligned stack and the next. */ |
# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1) |
/* The size of an array large to enough to hold all stacks, each with |
N elements. */ |
# define YYSTACK_BYTES(N) \ |
((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \ |
+ YYSTACK_GAP_MAXIMUM) |
/* Copy COUNT objects from FROM to TO. The source and destination do |
not overlap. */ |
# ifndef YYCOPY |
# if defined __GNUC__ && 1 < __GNUC__ |
# define YYCOPY(To, From, Count) \ |
__builtin_memcpy (To, From, (Count) * sizeof (*(From))) |
# else |
# define YYCOPY(To, From, Count) \ |
do \ |
{ \ |
YYSIZE_T yyi; \ |
for (yyi = 0; yyi < (Count); yyi++) \ |
(To)[yyi] = (From)[yyi]; \ |
} \ |
while (YYID (0)) |
# endif |
# endif |
/* Relocate STACK from its old location to the new one. The |
local variables YYSIZE and YYSTACKSIZE give the old and new number of |
elements in the stack, and YYPTR gives the new location of the |
stack. Advance YYPTR to a properly aligned location for the next |
stack. */ |
# define YYSTACK_RELOCATE(Stack) \ |
do \ |
{ \ |
YYSIZE_T yynewbytes; \ |
YYCOPY (&yyptr->Stack, Stack, yysize); \ |
Stack = &yyptr->Stack; \ |
yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \ |
yyptr += yynewbytes / sizeof (*yyptr); \ |
} \ |
while (YYID (0)) |
#endif |
/* YYFINAL -- State number of the termination state. */ |
#define YYFINAL 14 |
/* YYLAST -- Last index in YYTABLE. */ |
#define YYLAST 170 |
/* YYNTOKENS -- Number of terminals. */ |
#define YYNTOKENS 28 |
/* YYNNTS -- Number of nonterminals. */ |
#define YYNNTS 3 |
/* YYNRULES -- Number of rules. */ |
#define YYNRULES 26 |
/* YYNRULES -- Number of states. */ |
#define YYNSTATES 52 |
/* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX. */ |
#define YYUNDEFTOK 2 |
#define YYMAXUTOK 282 |
#define YYTRANSLATE(YYX) \ |
((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) |
/* YYTRANSLATE[YYLEX] -- Bison symbol number corresponding to YYLEX. */ |
static const yytype_uint8 yytranslate[] = |
{ |
0, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, |
2, 2, 2, 2, 2, 2, 1, 2, 3, 4, |
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27 |
}; |
#if YYDEBUG |
/* YYPRHS[YYN] -- Index of the first RHS symbol of rule number YYN in |
YYRHS. */ |
static const yytype_uint8 yyprhs[] = |
{ |
0, 0, 3, 5, 9, 13, 17, 21, 25, 29, |
33, 37, 41, 45, 49, 53, 57, 61, 65, 69, |
73, 77, 81, 84, 87, 90, 93 |
}; |
/* YYRHS -- A `-1'-separated list of the rules' RHS. */ |
static const yytype_int8 yyrhs[] = |
{ |
29, 0, -1, 30, -1, 4, 30, 5, -1, 30, |
6, 30, -1, 30, 7, 30, -1, 30, 8, 30, |
-1, 30, 9, 30, -1, 30, 10, 30, -1, 30, |
12, 30, -1, 30, 15, 30, -1, 30, 14, 30, |
-1, 30, 16, 30, -1, 30, 13, 30, -1, 30, |
11, 30, -1, 30, 18, 30, -1, 30, 17, 30, |
-1, 30, 20, 30, -1, 30, 19, 30, -1, 30, |
23, 30, -1, 30, 22, 30, -1, 30, 21, 30, |
-1, 25, 30, -1, 24, 30, -1, 19, 30, -1, |
20, 30, -1, 3, -1 |
}; |
/* YYRLINE[YYN] -- source line where rule number YYN was defined. */ |
static const yytype_uint8 yyrline[] = |
{ |
0, 153, 153, 159, 160, 161, 162, 163, 164, 165, |
166, 167, 168, 169, 170, 171, 172, 173, 174, 175, |
176, 181, 186, 187, 188, 189, 190 |
}; |
#endif |
#if YYDEBUG || YYERROR_VERBOSE || YYTOKEN_TABLE |
/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM. |
First, the terminals, then, starting at YYNTOKENS, nonterminals. */ |
static const char *const yytname[] = |
{ |
"$end", "error", "$undefined", "ARITH_NUM", "ARITH_LPAREN", |
"ARITH_RPAREN", "ARITH_OR", "ARITH_AND", "ARITH_BOR", "ARITH_BXOR", |
"ARITH_BAND", "ARITH_NE", "ARITH_EQ", "ARITH_LE", "ARITH_GE", "ARITH_GT", |
"ARITH_LT", "ARITH_RSHIFT", "ARITH_LSHIFT", "ARITH_SUB", "ARITH_ADD", |
"ARITH_REM", "ARITH_DIV", "ARITH_MUL", "ARITH_BNOT", "ARITH_NOT", |
"ARITH_UNARYPLUS", "ARITH_UNARYMINUS", "$accept", "exp", "expr", 0 |
}; |
#endif |
# ifdef YYPRINT |
/* YYTOKNUM[YYLEX-NUM] -- Internal token number corresponding to |
token YYLEX-NUM. */ |
static const yytype_uint16 yytoknum[] = |
{ |
0, 256, 257, 258, 259, 260, 261, 262, 263, 264, |
265, 266, 267, 268, 269, 270, 271, 272, 273, 274, |
275, 276, 277, 278, 279, 280, 281, 282 |
}; |
# endif |
/* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ |
static const yytype_uint8 yyr1[] = |
{ |
0, 28, 29, 30, 30, 30, 30, 30, 30, 30, |
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, |
30, 30, 30, 30, 30, 30, 30 |
}; |
/* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN. */ |
static const yytype_uint8 yyr2[] = |
{ |
0, 2, 1, 3, 3, 3, 3, 3, 3, 3, |
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, |
3, 3, 2, 2, 2, 2, 1 |
}; |
/* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state |
STATE-NUM when YYTABLE doesn't specify something else to do. Zero |
means the default is an error. */ |
static const yytype_uint8 yydefact[] = |
{ |
0, 26, 0, 0, 0, 0, 0, 0, 2, 0, |
24, 25, 23, 22, 1, 0, 0, 0, 0, 0, |
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
0, 0, 0, 3, 4, 5, 6, 7, 8, 14, |
9, 13, 11, 10, 12, 16, 15, 18, 17, 21, |
20, 19 |
}; |
/* YYDEFGOTO[NTERM-NUM]. */ |
static const yytype_int8 yydefgoto[] = |
{ |
-1, 7, 8 |
}; |
/* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing |
STATE-NUM. */ |
#define YYPACT_NINF -13 |
static const yytype_int16 yypact[] = |
{ |
28, -13, 28, 28, 28, 28, 28, 12, 67, 49, |
-13, -13, -13, -13, -13, 28, 28, 28, 28, 28, |
28, 28, 28, 28, 28, 28, 28, 28, 28, 28, |
28, 28, 28, -13, 84, 100, 115, 23, 128, 139, |
139, -12, -12, -12, -12, 144, 144, 147, 147, -13, |
-13, -13 |
}; |
/* YYPGOTO[NTERM-NUM]. */ |
static const yytype_int8 yypgoto[] = |
{ |
-13, -13, -2 |
}; |
/* YYTABLE[YYPACT[STATE-NUM]]. What to do in state STATE-NUM. If |
positive, shift that token. If negative, reduce the rule which |
number is the opposite. If zero, do what YYDEFACT says. |
If YYTABLE_NINF, syntax error. */ |
#define YYTABLE_NINF -1 |
static const yytype_uint8 yytable[] = |
{ |
9, 10, 11, 12, 13, 26, 27, 28, 29, 30, |
31, 32, 14, 34, 35, 36, 37, 38, 39, 40, |
41, 42, 43, 44, 45, 46, 47, 48, 49, 50, |
51, 1, 2, 19, 20, 21, 22, 23, 24, 25, |
26, 27, 28, 29, 30, 31, 32, 3, 4, 0, |
0, 0, 5, 6, 33, 15, 16, 17, 18, 19, |
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, |
30, 31, 32, 15, 16, 17, 18, 19, 20, 21, |
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, |
32, 16, 17, 18, 19, 20, 21, 22, 23, 24, |
25, 26, 27, 28, 29, 30, 31, 32, 17, 18, |
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, |
29, 30, 31, 32, 18, 19, 20, 21, 22, 23, |
24, 25, 26, 27, 28, 29, 30, 31, 32, 20, |
21, 22, 23, 24, 25, 26, 27, 28, 29, 30, |
31, 32, 22, 23, 24, 25, 26, 27, 28, 29, |
30, 31, 32, 28, 29, 30, 31, 32, 30, 31, |
32 |
}; |
static const yytype_int8 yycheck[] = |
{ |
2, 3, 4, 5, 6, 17, 18, 19, 20, 21, |
22, 23, 0, 15, 16, 17, 18, 19, 20, 21, |
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, |
32, 3, 4, 10, 11, 12, 13, 14, 15, 16, |
17, 18, 19, 20, 21, 22, 23, 19, 20, -1, |
-1, -1, 24, 25, 5, 6, 7, 8, 9, 10, |
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, |
21, 22, 23, 6, 7, 8, 9, 10, 11, 12, |
13, 14, 15, 16, 17, 18, 19, 20, 21, 22, |
23, 7, 8, 9, 10, 11, 12, 13, 14, 15, |
16, 17, 18, 19, 20, 21, 22, 23, 8, 9, |
10, 11, 12, 13, 14, 15, 16, 17, 18, 19, |
20, 21, 22, 23, 9, 10, 11, 12, 13, 14, |
15, 16, 17, 18, 19, 20, 21, 22, 23, 11, |
12, 13, 14, 15, 16, 17, 18, 19, 20, 21, |
22, 23, 13, 14, 15, 16, 17, 18, 19, 20, |
21, 22, 23, 19, 20, 21, 22, 23, 21, 22, |
23 |
}; |
/* YYSTOS[STATE-NUM] -- The (internal number of the) accessing |
symbol of state STATE-NUM. */ |
static const yytype_uint8 yystos[] = |
{ |
0, 3, 4, 19, 20, 24, 25, 29, 30, 30, |
30, 30, 30, 30, 0, 6, 7, 8, 9, 10, |
11, 12, 13, 14, 15, 16, 17, 18, 19, 20, |
21, 22, 23, 5, 30, 30, 30, 30, 30, 30, |
30, 30, 30, 30, 30, 30, 30, 30, 30, 30, |
30, 30 |
}; |
#define yyerrok (yyerrstatus = 0) |
#define yyclearin (yychar = YYEMPTY) |
#define YYEMPTY (-2) |
#define YYEOF 0 |
#define YYACCEPT goto yyacceptlab |
#define YYABORT goto yyabortlab |
#define YYERROR goto yyerrorlab |
/* Like YYERROR except do call yyerror. This remains here temporarily |
to ease the transition to the new meaning of YYERROR, for GCC. |
Once GCC version 2 has supplanted version 1, this can go. */ |
#define YYFAIL goto yyerrlab |
#define YYRECOVERING() (!!yyerrstatus) |
#define YYBACKUP(Token, Value) \ |
do \ |
if (yychar == YYEMPTY && yylen == 1) \ |
{ \ |
yychar = (Token); \ |
yylval = (Value); \ |
yytoken = YYTRANSLATE (yychar); \ |
YYPOPSTACK (1); \ |
goto yybackup; \ |
} \ |
else \ |
{ \ |
yyerror (YY_("syntax error: cannot back up")); \ |
YYERROR; \ |
} \ |
while (YYID (0)) |
#define YYTERROR 1 |
#define YYERRCODE 256 |
/* YYLLOC_DEFAULT -- Set CURRENT to span from RHS[1] to RHS[N]. |
If N is 0, then set CURRENT to the empty location which ends |
the previous symbol: RHS[0] (always defined). */ |
#define YYRHSLOC(Rhs, K) ((Rhs)[K]) |
#ifndef YYLLOC_DEFAULT |
# define YYLLOC_DEFAULT(Current, Rhs, N) \ |
do \ |
if (YYID (N)) \ |
{ \ |
(Current).first_line = YYRHSLOC (Rhs, 1).first_line; \ |
(Current).first_column = YYRHSLOC (Rhs, 1).first_column; \ |
(Current).last_line = YYRHSLOC (Rhs, N).last_line; \ |
(Current).last_column = YYRHSLOC (Rhs, N).last_column; \ |
} \ |
else \ |
{ \ |
(Current).first_line = (Current).last_line = \ |
YYRHSLOC (Rhs, 0).last_line; \ |
(Current).first_column = (Current).last_column = \ |
YYRHSLOC (Rhs, 0).last_column; \ |
} \ |
while (YYID (0)) |
#endif |
/* YY_LOCATION_PRINT -- Print the location on the stream. |
This macro was not mandated originally: define only if we know |
we won't break user code: when these are the locations we know. */ |
#ifndef YY_LOCATION_PRINT |
# if YYLTYPE_IS_TRIVIAL |
# define YY_LOCATION_PRINT(File, Loc) \ |
fprintf (File, "%d.%d-%d.%d", \ |
(Loc).first_line, (Loc).first_column, \ |
(Loc).last_line, (Loc).last_column) |
# else |
# define YY_LOCATION_PRINT(File, Loc) ((void) 0) |
# endif |
#endif |
/* YYLEX -- calling `yylex' with the right arguments. */ |
#ifdef YYLEX_PARAM |
# define YYLEX yylex (YYLEX_PARAM) |
#else |
# define YYLEX yylex () |
#endif |
/* Enable debugging if requested. */ |
#if YYDEBUG |
# ifndef YYFPRINTF |
# include <stdio.h> /* INFRINGES ON USER NAME SPACE */ |
# define YYFPRINTF fprintf |
# endif |
# define YYDPRINTF(Args) \ |
do { \ |
if (yydebug) \ |
YYFPRINTF Args; \ |
} while (YYID (0)) |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \ |
do { \ |
if (yydebug) \ |
{ \ |
YYFPRINTF (stderr, "%s ", Title); \ |
yy_symbol_print (stderr, \ |
Type, Value); \ |
YYFPRINTF (stderr, "\n"); \ |
} \ |
} while (YYID (0)) |
/*--------------------------------. |
| Print this symbol on YYOUTPUT. | |
`--------------------------------*/ |
/*ARGSUSED*/ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static void |
yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) |
#else |
static void |
yy_symbol_value_print (yyoutput, yytype, yyvaluep) |
FILE *yyoutput; |
int yytype; |
YYSTYPE const * const yyvaluep; |
#endif |
{ |
if (!yyvaluep) |
return; |
# ifdef YYPRINT |
if (yytype < YYNTOKENS) |
YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep); |
# else |
YYUSE (yyoutput); |
# endif |
switch (yytype) |
{ |
default: |
break; |
} |
} |
/*--------------------------------. |
| Print this symbol on YYOUTPUT. | |
`--------------------------------*/ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static void |
yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep) |
#else |
static void |
yy_symbol_print (yyoutput, yytype, yyvaluep) |
FILE *yyoutput; |
int yytype; |
YYSTYPE const * const yyvaluep; |
#endif |
{ |
if (yytype < YYNTOKENS) |
YYFPRINTF (yyoutput, "token %s (", yytname[yytype]); |
else |
YYFPRINTF (yyoutput, "nterm %s (", yytname[yytype]); |
yy_symbol_value_print (yyoutput, yytype, yyvaluep); |
YYFPRINTF (yyoutput, ")"); |
} |
/*------------------------------------------------------------------. |
| yy_stack_print -- Print the state stack from its BOTTOM up to its | |
| TOP (included). | |
`------------------------------------------------------------------*/ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static void |
yy_stack_print (yytype_int16 *bottom, yytype_int16 *top) |
#else |
static void |
yy_stack_print (bottom, top) |
yytype_int16 *bottom; |
yytype_int16 *top; |
#endif |
{ |
YYFPRINTF (stderr, "Stack now"); |
for (; bottom <= top; ++bottom) |
YYFPRINTF (stderr, " %d", *bottom); |
YYFPRINTF (stderr, "\n"); |
} |
# define YY_STACK_PRINT(Bottom, Top) \ |
do { \ |
if (yydebug) \ |
yy_stack_print ((Bottom), (Top)); \ |
} while (YYID (0)) |
/*------------------------------------------------. |
| Report that the YYRULE is going to be reduced. | |
`------------------------------------------------*/ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static void |
yy_reduce_print (YYSTYPE *yyvsp, int yyrule) |
#else |
static void |
yy_reduce_print (yyvsp, yyrule) |
YYSTYPE *yyvsp; |
int yyrule; |
#endif |
{ |
int yynrhs = yyr2[yyrule]; |
int yyi; |
unsigned long int yylno = yyrline[yyrule]; |
YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n", |
yyrule - 1, yylno); |
/* The symbols being reduced. */ |
for (yyi = 0; yyi < yynrhs; yyi++) |
{ |
fprintf (stderr, " $%d = ", yyi + 1); |
yy_symbol_print (stderr, yyrhs[yyprhs[yyrule] + yyi], |
&(yyvsp[(yyi + 1) - (yynrhs)]) |
); |
fprintf (stderr, "\n"); |
} |
} |
# define YY_REDUCE_PRINT(Rule) \ |
do { \ |
if (yydebug) \ |
yy_reduce_print (yyvsp, Rule); \ |
} while (YYID (0)) |
/* Nonzero means print parse trace. It is left uninitialized so that |
multiple parsers can coexist. */ |
int yydebug; |
#else /* !YYDEBUG */ |
# define YYDPRINTF(Args) |
# define YY_SYMBOL_PRINT(Title, Type, Value, Location) |
# define YY_STACK_PRINT(Bottom, Top) |
# define YY_REDUCE_PRINT(Rule) |
#endif /* !YYDEBUG */ |
/* YYINITDEPTH -- initial size of the parser's stacks. */ |
#ifndef YYINITDEPTH |
# define YYINITDEPTH 200 |
#endif |
/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only |
if the built-in stack extension method is used). |
Do not make this value too large; the results are undefined if |
YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH) |
evaluated with infinite-precision integer arithmetic. */ |
#ifndef YYMAXDEPTH |
# define YYMAXDEPTH 10000 |
#endif |
#if YYERROR_VERBOSE |
# ifndef yystrlen |
# if defined __GLIBC__ && defined _STRING_H |
# define yystrlen strlen |
# else |
/* Return the length of YYSTR. */ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static YYSIZE_T |
yystrlen (const char *yystr) |
#else |
static YYSIZE_T |
yystrlen (yystr) |
const char *yystr; |
#endif |
{ |
YYSIZE_T yylen; |
for (yylen = 0; yystr[yylen]; yylen++) |
continue; |
return yylen; |
} |
# endif |
# endif |
# ifndef yystpcpy |
# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE |
# define yystpcpy stpcpy |
# else |
/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in |
YYDEST. */ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static char * |
yystpcpy (char *yydest, const char *yysrc) |
#else |
static char * |
yystpcpy (yydest, yysrc) |
char *yydest; |
const char *yysrc; |
#endif |
{ |
char *yyd = yydest; |
const char *yys = yysrc; |
while ((*yyd++ = *yys++) != '\0') |
continue; |
return yyd - 1; |
} |
# endif |
# endif |
# ifndef yytnamerr |
/* Copy to YYRES the contents of YYSTR after stripping away unnecessary |
quotes and backslashes, so that it's suitable for yyerror. The |
heuristic is that double-quoting is unnecessary unless the string |
contains an apostrophe, a comma, or backslash (other than |
backslash-backslash). YYSTR is taken from yytname. If YYRES is |
null, do not copy; instead, return the length of what the result |
would have been. */ |
static YYSIZE_T |
yytnamerr (char *yyres, const char *yystr) |
{ |
if (*yystr == '"') |
{ |
YYSIZE_T yyn = 0; |
char const *yyp = yystr; |
for (;;) |
switch (*++yyp) |
{ |
case '\'': |
case ',': |
goto do_not_strip_quotes; |
case '\\': |
if (*++yyp != '\\') |
goto do_not_strip_quotes; |
/* Fall through. */ |
default: |
if (yyres) |
yyres[yyn] = *yyp; |
yyn++; |
break; |
case '"': |
if (yyres) |
yyres[yyn] = '\0'; |
return yyn; |
} |
do_not_strip_quotes: ; |
} |
if (! yyres) |
return yystrlen (yystr); |
return yystpcpy (yyres, yystr) - yyres; |
} |
# endif |
/* Copy into YYRESULT an error message about the unexpected token |
YYCHAR while in state YYSTATE. Return the number of bytes copied, |
including the terminating null byte. If YYRESULT is null, do not |
copy anything; just return the number of bytes that would be |
copied. As a special case, return 0 if an ordinary "syntax error" |
message will do. Return YYSIZE_MAXIMUM if overflow occurs during |
size calculation. */ |
static YYSIZE_T |
yysyntax_error (char *yyresult, int yystate, int yychar) |
{ |
int yyn = yypact[yystate]; |
if (! (YYPACT_NINF < yyn && yyn <= YYLAST)) |
return 0; |
else |
{ |
int yytype = YYTRANSLATE (yychar); |
YYSIZE_T yysize0 = yytnamerr (0, yytname[yytype]); |
YYSIZE_T yysize = yysize0; |
YYSIZE_T yysize1; |
int yysize_overflow = 0; |
enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 }; |
char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM]; |
int yyx; |
# if 0 |
/* This is so xgettext sees the translatable formats that are |
constructed on the fly. */ |
YY_("syntax error, unexpected %s"); |
YY_("syntax error, unexpected %s, expecting %s"); |
YY_("syntax error, unexpected %s, expecting %s or %s"); |
YY_("syntax error, unexpected %s, expecting %s or %s or %s"); |
YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"); |
# endif |
char *yyfmt; |
char const *yyf; |
static char const yyunexpected[] = "syntax error, unexpected %s"; |
static char const yyexpecting[] = ", expecting %s"; |
static char const yyor[] = " or %s"; |
char yyformat[sizeof yyunexpected |
+ sizeof yyexpecting - 1 |
+ ((YYERROR_VERBOSE_ARGS_MAXIMUM - 2) |
* (sizeof yyor - 1))]; |
char const *yyprefix = yyexpecting; |
/* Start YYX at -YYN if negative to avoid negative indexes in |
YYCHECK. */ |
int yyxbegin = yyn < 0 ? -yyn : 0; |
/* Stay within bounds of both yycheck and yytname. */ |
int yychecklim = YYLAST - yyn + 1; |
int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS; |
int yycount = 1; |
yyarg[0] = yytname[yytype]; |
yyfmt = yystpcpy (yyformat, yyunexpected); |
for (yyx = yyxbegin; yyx < yyxend; ++yyx) |
if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR) |
{ |
if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM) |
{ |
yycount = 1; |
yysize = yysize0; |
yyformat[sizeof yyunexpected - 1] = '\0'; |
break; |
} |
yyarg[yycount++] = yytname[yyx]; |
yysize1 = yysize + yytnamerr (0, yytname[yyx]); |
yysize_overflow |= (yysize1 < yysize); |
yysize = yysize1; |
yyfmt = yystpcpy (yyfmt, yyprefix); |
yyprefix = yyor; |
} |
yyf = YY_(yyformat); |
yysize1 = yysize + yystrlen (yyf); |
yysize_overflow |= (yysize1 < yysize); |
yysize = yysize1; |
if (yysize_overflow) |
return YYSIZE_MAXIMUM; |
if (yyresult) |
{ |
/* Avoid sprintf, as that infringes on the user's name space. |
Don't have undefined behavior even if the translation |
produced a string with the wrong number of "%s"s. */ |
char *yyp = yyresult; |
int yyi = 0; |
while ((*yyp = *yyf) != '\0') |
{ |
if (*yyp == '%' && yyf[1] == 's' && yyi < yycount) |
{ |
yyp += yytnamerr (yyp, yyarg[yyi++]); |
yyf += 2; |
} |
else |
{ |
yyp++; |
yyf++; |
} |
} |
} |
return yysize; |
} |
} |
#endif /* YYERROR_VERBOSE */ |
/*-----------------------------------------------. |
| Release the memory associated to this symbol. | |
`-----------------------------------------------*/ |
/*ARGSUSED*/ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
static void |
yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep) |
#else |
static void |
yydestruct (yymsg, yytype, yyvaluep) |
const char *yymsg; |
int yytype; |
YYSTYPE *yyvaluep; |
#endif |
{ |
YYUSE (yyvaluep); |
if (!yymsg) |
yymsg = "Deleting"; |
YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp); |
switch (yytype) |
{ |
default: |
break; |
} |
} |
/* Prevent warnings from -Wmissing-prototypes. */ |
#ifdef YYPARSE_PARAM |
#if defined __STDC__ || defined __cplusplus |
int yyparse (void *YYPARSE_PARAM); |
#else |
int yyparse (); |
#endif |
#else /* ! YYPARSE_PARAM */ |
#if defined __STDC__ || defined __cplusplus |
int yyparse (void); |
#else |
int yyparse (); |
#endif |
#endif /* ! YYPARSE_PARAM */ |
/* The look-ahead symbol. */ |
int yychar; |
/* The semantic value of the look-ahead symbol. */ |
YYSTYPE yylval; |
/* Number of syntax errors so far. */ |
int yynerrs; |
/*----------. |
| yyparse. | |
`----------*/ |
#ifdef YYPARSE_PARAM |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
int |
yyparse (void *YYPARSE_PARAM) |
#else |
int |
yyparse (YYPARSE_PARAM) |
void *YYPARSE_PARAM; |
#endif |
#else /* ! YYPARSE_PARAM */ |
#if (defined __STDC__ || defined __C99__FUNC__ \ |
|| defined __cplusplus || defined _MSC_VER) |
int |
yyparse (void) |
#else |
int |
yyparse () |
#endif |
#endif |
{ |
int yystate; |
int yyn; |
int yyresult; |
/* Number of tokens to shift before error messages enabled. */ |
int yyerrstatus; |
/* Look-ahead token as an internal (translated) token number. */ |
int yytoken = 0; |
#if YYERROR_VERBOSE |
/* Buffer for error messages, and its allocated size. */ |
char yymsgbuf[128]; |
char *yymsg = yymsgbuf; |
YYSIZE_T yymsg_alloc = sizeof yymsgbuf; |
#endif |
/* Three stacks and their tools: |
`yyss': related to states, |
`yyvs': related to semantic values, |
`yyls': related to locations. |
Refer to the stacks thru separate pointers, to allow yyoverflow |
to reallocate them elsewhere. */ |
/* The state stack. */ |
yytype_int16 yyssa[YYINITDEPTH]; |
yytype_int16 *yyss = yyssa; |
yytype_int16 *yyssp; |
/* The semantic value stack. */ |
YYSTYPE yyvsa[YYINITDEPTH]; |
YYSTYPE *yyvs = yyvsa; |
YYSTYPE *yyvsp; |
#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N)) |
YYSIZE_T yystacksize = YYINITDEPTH; |
/* The variables used to return semantic value and location from the |
action routines. */ |
YYSTYPE yyval; |
/* The number of symbols on the RHS of the reduced rule. |
Keep to zero when no symbol should be popped. */ |
int yylen = 0; |
YYDPRINTF ((stderr, "Starting parse\n")); |
yystate = 0; |
yyerrstatus = 0; |
yynerrs = 0; |
yychar = YYEMPTY; /* Cause a token to be read. */ |
/* Initialize stack pointers. |
Waste one element of value and location stack |
so that they stay on the same level as the state stack. |
The wasted elements are never initialized. */ |
yyssp = yyss; |
yyvsp = yyvs; |
goto yysetstate; |
/*------------------------------------------------------------. |
| yynewstate -- Push a new state, which is found in yystate. | |
`------------------------------------------------------------*/ |
yynewstate: |
/* In all cases, when you get here, the value and location stacks |
have just been pushed. So pushing a state here evens the stacks. */ |
yyssp++; |
yysetstate: |
*yyssp = yystate; |
if (yyss + yystacksize - 1 <= yyssp) |
{ |
/* Get the current used size of the three stacks, in elements. */ |
YYSIZE_T yysize = yyssp - yyss + 1; |
#ifdef yyoverflow |
{ |
/* Give user a chance to reallocate the stack. Use copies of |
these so that the &'s don't force the real ones into |
memory. */ |
YYSTYPE *yyvs1 = yyvs; |
yytype_int16 *yyss1 = yyss; |
/* Each stack pointer address is followed by the size of the |
data in use in that stack, in bytes. This used to be a |
conditional around just the two extra args, but that might |
be undefined if yyoverflow is a macro. */ |
yyoverflow (YY_("memory exhausted"), |
&yyss1, yysize * sizeof (*yyssp), |
&yyvs1, yysize * sizeof (*yyvsp), |
&yystacksize); |
yyss = yyss1; |
yyvs = yyvs1; |
} |
#else /* no yyoverflow */ |
# ifndef YYSTACK_RELOCATE |
goto yyexhaustedlab; |
# else |
/* Extend the stack our own way. */ |
if (YYMAXDEPTH <= yystacksize) |
goto yyexhaustedlab; |
yystacksize *= 2; |
if (YYMAXDEPTH < yystacksize) |
yystacksize = YYMAXDEPTH; |
{ |
yytype_int16 *yyss1 = yyss; |
union yyalloc *yyptr = |
(union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize)); |
if (! yyptr) |
goto yyexhaustedlab; |
YYSTACK_RELOCATE (yyss); |
YYSTACK_RELOCATE (yyvs); |
# undef YYSTACK_RELOCATE |
if (yyss1 != yyssa) |
YYSTACK_FREE (yyss1); |
} |
# endif |
#endif /* no yyoverflow */ |
yyssp = yyss + yysize - 1; |
yyvsp = yyvs + yysize - 1; |
YYDPRINTF ((stderr, "Stack size increased to %lu\n", |
(unsigned long int) yystacksize)); |
if (yyss + yystacksize - 1 <= yyssp) |
YYABORT; |
} |
YYDPRINTF ((stderr, "Entering state %d\n", yystate)); |
goto yybackup; |
/*-----------. |
| yybackup. | |
`-----------*/ |
yybackup: |
/* Do appropriate processing given the current state. Read a |
look-ahead token if we need one and don't already have one. */ |
/* First try to decide what to do without reference to look-ahead token. */ |
yyn = yypact[yystate]; |
if (yyn == YYPACT_NINF) |
goto yydefault; |
/* Not known => get a look-ahead token if don't already have one. */ |
/* YYCHAR is either YYEMPTY or YYEOF or a valid look-ahead symbol. */ |
if (yychar == YYEMPTY) |
{ |
YYDPRINTF ((stderr, "Reading a token: ")); |
yychar = YYLEX; |
} |
if (yychar <= YYEOF) |
{ |
yychar = yytoken = YYEOF; |
YYDPRINTF ((stderr, "Now at end of input.\n")); |
} |
else |
{ |
yytoken = YYTRANSLATE (yychar); |
YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc); |
} |
/* If the proper action on seeing token YYTOKEN is to reduce or to |
detect an error, take that action. */ |
yyn += yytoken; |
if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken) |
goto yydefault; |
yyn = yytable[yyn]; |
if (yyn <= 0) |
{ |
if (yyn == 0 || yyn == YYTABLE_NINF) |
goto yyerrlab; |
yyn = -yyn; |
goto yyreduce; |
} |
if (yyn == YYFINAL) |
YYACCEPT; |
/* Count tokens shifted since error; after three, turn off error |
status. */ |
if (yyerrstatus) |
yyerrstatus--; |
/* Shift the look-ahead token. */ |
YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc); |
/* Discard the shifted token unless it is eof. */ |
if (yychar != YYEOF) |
yychar = YYEMPTY; |
yystate = yyn; |
*++yyvsp = yylval; |
goto yynewstate; |
/*-----------------------------------------------------------. |
| yydefault -- do the default action for the current state. | |
`-----------------------------------------------------------*/ |
yydefault: |
yyn = yydefact[yystate]; |
if (yyn == 0) |
goto yyerrlab; |
goto yyreduce; |
/*-----------------------------. |
| yyreduce -- Do a reduction. | |
`-----------------------------*/ |
yyreduce: |
/* yyn is the number of a rule to reduce with. */ |
yylen = yyr2[yyn]; |
/* If YYLEN is nonzero, implement the default value of the action: |
`$$ = $1'. |
Otherwise, the following line sets YYVAL to garbage. |
This behavior is undocumented and Bison |
users should not rely upon it. Assigning to YYVAL |
unconditionally makes the parser a bit smaller, and it avoids a |
GCC warning that YYVAL may be used uninitialized. */ |
yyval = yyvsp[1-yylen]; |
YY_REDUCE_PRINT (yyn); |
switch (yyn) |
{ |
case 2: |
#line 153 "arith.y" |
{ |
return ((yyvsp[(1) - (1)])); |
} |
break; |
case 3: |
#line 159 "arith.y" |
{ (yyval) = (yyvsp[(2) - (3)]); } |
break; |
case 4: |
#line 160 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) ? (yyvsp[(1) - (3)]) : (yyvsp[(3) - (3)]) ? (yyvsp[(3) - (3)]) : 0; } |
break; |
case 5: |
#line 161 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) ? ( (yyvsp[(3) - (3)]) ? (yyvsp[(3) - (3)]) : 0 ) : 0; } |
break; |
case 6: |
#line 162 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) | (yyvsp[(3) - (3)]); } |
break; |
case 7: |
#line 163 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) ^ (yyvsp[(3) - (3)]); } |
break; |
case 8: |
#line 164 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) & (yyvsp[(3) - (3)]); } |
break; |
case 9: |
#line 165 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) == (yyvsp[(3) - (3)]); } |
break; |
case 10: |
#line 166 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) > (yyvsp[(3) - (3)]); } |
break; |
case 11: |
#line 167 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) >= (yyvsp[(3) - (3)]); } |
break; |
case 12: |
#line 168 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) < (yyvsp[(3) - (3)]); } |
break; |
case 13: |
#line 169 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) <= (yyvsp[(3) - (3)]); } |
break; |
case 14: |
#line 170 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) != (yyvsp[(3) - (3)]); } |
break; |
case 15: |
#line 171 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) << (yyvsp[(3) - (3)]); } |
break; |
case 16: |
#line 172 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) >> (yyvsp[(3) - (3)]); } |
break; |
case 17: |
#line 173 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) + (yyvsp[(3) - (3)]); } |
break; |
case 18: |
#line 174 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) - (yyvsp[(3) - (3)]); } |
break; |
case 19: |
#line 175 "arith.y" |
{ (yyval) = (yyvsp[(1) - (3)]) * (yyvsp[(3) - (3)]); } |
break; |
case 20: |
#line 176 "arith.y" |
{ |
if ((yyvsp[(3) - (3)]) == 0) |
yyerror("division by zero"); |
(yyval) = (yyvsp[(1) - (3)]) / (yyvsp[(3) - (3)]); |
} |
break; |
case 21: |
#line 181 "arith.y" |
{ |
if ((yyvsp[(3) - (3)]) == 0) |
yyerror("division by zero"); |
(yyval) = (yyvsp[(1) - (3)]) % (yyvsp[(3) - (3)]); |
} |
break; |
case 22: |
#line 186 "arith.y" |
{ (yyval) = !((yyvsp[(2) - (2)])); } |
break; |
case 23: |
#line 187 "arith.y" |
{ (yyval) = ~((yyvsp[(2) - (2)])); } |
break; |
case 24: |
#line 188 "arith.y" |
{ (yyval) = -((yyvsp[(2) - (2)])); } |
break; |
case 25: |
#line 189 "arith.y" |
{ (yyval) = (yyvsp[(2) - (2)]); } |
break; |
/* Line 1267 of yacc.c. */ |
#line 1682 "y.tab.c" |
default: break; |
} |
YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc); |
YYPOPSTACK (yylen); |
yylen = 0; |
YY_STACK_PRINT (yyss, yyssp); |
*++yyvsp = yyval; |
/* Now `shift' the result of the reduction. Determine what state |
that goes to, based on the state we popped back to and the rule |
number reduced by. */ |
yyn = yyr1[yyn]; |
yystate = yypgoto[yyn - YYNTOKENS] + *yyssp; |
if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp) |
yystate = yytable[yystate]; |
else |
yystate = yydefgoto[yyn - YYNTOKENS]; |
goto yynewstate; |
/*------------------------------------. |
| yyerrlab -- here on detecting error | |
`------------------------------------*/ |
yyerrlab: |
/* If not already recovering from an error, report this error. */ |
if (!yyerrstatus) |
{ |
++yynerrs; |
#if ! YYERROR_VERBOSE |
yyerror (YY_("syntax error")); |
#else |
{ |
YYSIZE_T yysize = yysyntax_error (0, yystate, yychar); |
if (yymsg_alloc < yysize && yymsg_alloc < YYSTACK_ALLOC_MAXIMUM) |
{ |
YYSIZE_T yyalloc = 2 * yysize; |
if (! (yysize <= yyalloc && yyalloc <= YYSTACK_ALLOC_MAXIMUM)) |
yyalloc = YYSTACK_ALLOC_MAXIMUM; |
if (yymsg != yymsgbuf) |
YYSTACK_FREE (yymsg); |
yymsg = (char *) YYSTACK_ALLOC (yyalloc); |
if (yymsg) |
yymsg_alloc = yyalloc; |
else |
{ |
yymsg = yymsgbuf; |
yymsg_alloc = sizeof yymsgbuf; |
} |
} |
if (0 < yysize && yysize <= yymsg_alloc) |
{ |
(void) yysyntax_error (yymsg, yystate, yychar); |
yyerror (yymsg); |
} |
else |
{ |
yyerror (YY_("syntax error")); |
if (yysize != 0) |
goto yyexhaustedlab; |
} |
} |
#endif |
} |
if (yyerrstatus == 3) |
{ |
/* If just tried and failed to reuse look-ahead token after an |
error, discard it. */ |
if (yychar <= YYEOF) |
{ |
/* Return failure if at end of input. */ |
if (yychar == YYEOF) |
YYABORT; |
} |
else |
{ |
yydestruct ("Error: discarding", |
yytoken, &yylval); |
yychar = YYEMPTY; |
} |
} |
/* Else will try to reuse look-ahead token after shifting the error |
token. */ |
goto yyerrlab1; |
/*---------------------------------------------------. |
| yyerrorlab -- error raised explicitly by YYERROR. | |
`---------------------------------------------------*/ |
yyerrorlab: |
/* Pacify compilers like GCC when the user code never invokes |
YYERROR and the label yyerrorlab therefore never appears in user |
code. */ |
if (/*CONSTCOND*/ 0) |
goto yyerrorlab; |
/* Do not reclaim the symbols of the rule which action triggered |
this YYERROR. */ |
YYPOPSTACK (yylen); |
yylen = 0; |
YY_STACK_PRINT (yyss, yyssp); |
yystate = *yyssp; |
goto yyerrlab1; |
/*-------------------------------------------------------------. |
| yyerrlab1 -- common code for both syntax error and YYERROR. | |
`-------------------------------------------------------------*/ |
yyerrlab1: |
yyerrstatus = 3; /* Each real token shifted decrements this. */ |
for (;;) |
{ |
yyn = yypact[yystate]; |
if (yyn != YYPACT_NINF) |
{ |
yyn += YYTERROR; |
if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR) |
{ |
yyn = yytable[yyn]; |
if (0 < yyn) |
break; |
} |
} |
/* Pop the current state because it cannot handle the error token. */ |
if (yyssp == yyss) |
YYABORT; |
yydestruct ("Error: popping", |
yystos[yystate], yyvsp); |
YYPOPSTACK (1); |
yystate = *yyssp; |
YY_STACK_PRINT (yyss, yyssp); |
} |
if (yyn == YYFINAL) |
YYACCEPT; |
*++yyvsp = yylval; |
/* Shift the error token. */ |
YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp); |
yystate = yyn; |
goto yynewstate; |
/*-------------------------------------. |
| yyacceptlab -- YYACCEPT comes here. | |
`-------------------------------------*/ |
yyacceptlab: |
yyresult = 0; |
goto yyreturn; |
/*-----------------------------------. |
| yyabortlab -- YYABORT comes here. | |
`-----------------------------------*/ |
yyabortlab: |
yyresult = 1; |
goto yyreturn; |
#ifndef yyoverflow |
/*-------------------------------------------------. |
| yyexhaustedlab -- memory exhaustion comes here. | |
`-------------------------------------------------*/ |
yyexhaustedlab: |
yyerror (YY_("memory exhausted")); |
yyresult = 2; |
/* Fall through. */ |
#endif |
yyreturn: |
if (yychar != YYEOF && yychar != YYEMPTY) |
yydestruct ("Cleanup: discarding lookahead", |
yytoken, &yylval); |
/* Do not reclaim the symbols of the rule which action triggered |
this YYABORT or YYACCEPT. */ |
YYPOPSTACK (yylen); |
YY_STACK_PRINT (yyss, yyssp); |
while (yyssp != yyss) |
{ |
yydestruct ("Cleanup: popping", |
yystos[*yyssp], yyvsp); |
YYPOPSTACK (1); |
} |
#ifndef yyoverflow |
if (yyss != yyssa) |
YYSTACK_FREE (yyss); |
#endif |
#if YYERROR_VERBOSE |
if (yymsg != yymsgbuf) |
YYSTACK_FREE (yymsg); |
#endif |
/* Make sure YYID is used. */ |
return YYID (yyresult); |
} |
#line 192 "arith.y" |
void |
yyerror(s) |
const char *s; |
{ |
yyclearin; |
arith_lex_reset(); /* reprime lex */ |
error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); |
/* NOTREACHED */ |
} |
/branches/dd/uspace/app/ash/redir.h |
---|
0,0 → 1,53 |
/* $NetBSD: redir.h,v 1.12 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)redir.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* flags passed to redirect */ |
#define REDIR_PUSH 01 /* save previous values of file descriptors */ |
#define REDIR_BACKQ 02 /* save the command output in memory */ |
extern int fd2; |
union node; |
void redirect (union node *, int); |
void popredir (void); |
int fd0_redirected_p (void); |
void clearredir (void); |
int copyfd (int, int); |
/branches/dd/uspace/app/ash/trap.h |
---|
0,0 → 1,51 |
/* $NetBSD: trap.h,v 1.14 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)trap.h 8.3 (Berkeley) 6/5/95 |
*/ |
extern int pendingsigs; |
int trapcmd (int, char **); |
void clear_traps (void); |
void setsignal (int); |
void ignoresig (int); |
void onsig (int); |
void dotrap (void); |
void setinteractive (int); |
void exitshell (int) __attribute__((noreturn)); |
int decode_signal (const char *); |
/branches/dd/uspace/app/ash/arith.h |
---|
0,0 → 1,107 |
/* A Bison parser, made by GNU Bison 2.3. */ |
/* Skeleton interface for Bison's Yacc-like parsers in C |
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006 |
Free Software Foundation, Inc. |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2, or (at your option) |
any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 51 Franklin Street, Fifth Floor, |
Boston, MA 02110-1301, USA. */ |
/* As a special exception, you may create a larger work that contains |
part or all of the Bison parser skeleton and distribute that work |
under terms of your choice, so long as that work isn't itself a |
parser generator using the skeleton or a modified version thereof |
as a parser skeleton. Alternatively, if you modify or redistribute |
the parser skeleton itself, you may (at your option) remove this |
special exception, which will cause the skeleton and the resulting |
Bison output files to be licensed under the GNU General Public |
License without this special exception. |
This special exception was added by the Free Software Foundation in |
version 2.2 of Bison. */ |
/* Tokens. */ |
#ifndef YYTOKENTYPE |
# define YYTOKENTYPE |
/* Put the tokens into the symbol table, so that GDB and other debuggers |
know about them. */ |
enum yytokentype { |
ARITH_NUM = 258, |
ARITH_LPAREN = 259, |
ARITH_RPAREN = 260, |
ARITH_OR = 261, |
ARITH_AND = 262, |
ARITH_BOR = 263, |
ARITH_BXOR = 264, |
ARITH_BAND = 265, |
ARITH_NE = 266, |
ARITH_EQ = 267, |
ARITH_LE = 268, |
ARITH_GE = 269, |
ARITH_GT = 270, |
ARITH_LT = 271, |
ARITH_RSHIFT = 272, |
ARITH_LSHIFT = 273, |
ARITH_SUB = 274, |
ARITH_ADD = 275, |
ARITH_REM = 276, |
ARITH_DIV = 277, |
ARITH_MUL = 278, |
ARITH_BNOT = 279, |
ARITH_NOT = 280, |
ARITH_UNARYPLUS = 281, |
ARITH_UNARYMINUS = 282 |
}; |
#endif |
/* Tokens. */ |
#define ARITH_NUM 258 |
#define ARITH_LPAREN 259 |
#define ARITH_RPAREN 260 |
#define ARITH_OR 261 |
#define ARITH_AND 262 |
#define ARITH_BOR 263 |
#define ARITH_BXOR 264 |
#define ARITH_BAND 265 |
#define ARITH_NE 266 |
#define ARITH_EQ 267 |
#define ARITH_LE 268 |
#define ARITH_GE 269 |
#define ARITH_GT 270 |
#define ARITH_LT 271 |
#define ARITH_RSHIFT 272 |
#define ARITH_LSHIFT 273 |
#define ARITH_SUB 274 |
#define ARITH_ADD 275 |
#define ARITH_REM 276 |
#define ARITH_DIV 277 |
#define ARITH_MUL 278 |
#define ARITH_BNOT 279 |
#define ARITH_NOT 280 |
#define ARITH_UNARYPLUS 281 |
#define ARITH_UNARYMINUS 282 |
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED |
typedef int YYSTYPE; |
# define yystype YYSTYPE /* obsolescent; will be withdrawn */ |
# define YYSTYPE_IS_DECLARED 1 |
# define YYSTYPE_IS_TRIVIAL 1 |
#endif |
extern YYSTYPE yylval; |
/branches/dd/uspace/app/ash/expand.c |
---|
0,0 → 1,1750 |
/* $NetBSD: expand.c,v 1.49 2000/03/13 22:47:19 soren Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)expand.c 8.5 (Berkeley) 5/15/95"; |
#else |
__RCSID("$NetBSD: expand.c,v 1.49 2000/03/13 22:47:19 soren Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/types.h> |
#include <sys/time.h> |
#include <sys/stat.h> |
#include <errno.h> |
#include <dirent.h> |
#include <unistd.h> |
#include <pwd.h> |
#include <stdlib.h> |
#include <stdio.h> |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
#include <fnmatch.h> |
#include <glob.h> |
#endif |
/* |
* Routines to expand arguments to commands. We have to deal with |
* backquotes, shell variables, and file metacharacters. |
*/ |
#include "shell.h" |
#include "main.h" |
#include "nodes.h" |
#include "eval.h" |
#include "expand.h" |
#include "syntax.h" |
#include "parser.h" |
#include "jobs.h" |
#include "options.h" |
#include "var.h" |
#include "input.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "mystring.h" |
#include "show.h" |
/* |
* Structure specifying which parts of the string should be searched |
* for IFS characters. |
*/ |
struct ifsregion { |
struct ifsregion *next; /* next region in list */ |
int begoff; /* offset of start of region */ |
int endoff; /* offset of end of region */ |
int nulonly; /* search for nul bytes only */ |
}; |
char *expdest; /* output of current string */ |
struct nodelist *argbackq; /* list of back quote expressions */ |
struct ifsregion ifsfirst; /* first struct in list of ifs regions */ |
struct ifsregion *ifslastp; /* last struct in list */ |
struct arglist exparg; /* holds expanded arg list */ |
STATIC void argstr (char *, int); |
STATIC char *exptilde (char *, int); |
STATIC void expbackq (union node *, int, int); |
STATIC int subevalvar (char *, char *, int, int, int, int); |
STATIC char *evalvar (char *, int); |
STATIC int varisset (char *, int); |
STATIC char *strtodest (char *, int, int); |
STATIC void varvalue (char *, int, int); |
STATIC void recordregion (int, int, int); |
STATIC void removerecordregions (int); |
STATIC void ifsbreakup (char *, struct arglist *); |
STATIC void ifsfree (void); |
STATIC void expandmeta (struct strlist *, int); |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
STATIC const char *preglob (const char *); |
STATIC void addglob (const glob_t *); |
#else |
STATIC void expmeta (char *, char *); |
#endif |
STATIC void addfname (char *); |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
STATIC int patmatch (char *, char *, int); |
STATIC int patmatch2 (char *, char *, int); |
STATIC char * _rmescapes (char *, int); |
#else |
STATIC struct strlist *expsort (struct strlist *); |
STATIC struct strlist *msort (struct strlist *, int); |
STATIC int pmatch (char *, char *, int); |
#define patmatch2 patmatch |
#endif |
STATIC char *cvtnum (int, char *); |
/* |
* Expand shell variables and backquotes inside a here document. |
*/ |
void |
expandhere(arg, fd) |
union node *arg; /* the document */ |
int fd; /* where to write the expanded version */ |
{ |
herefd = fd; |
expandarg(arg, (struct arglist *)NULL, 0); |
xwrite(fd, stackblock(), expdest - stackblock()); |
} |
/* |
* Perform variable substitution and command substitution on an argument, |
* placing the resulting list of arguments in arglist. If EXP_FULL is true, |
* perform splitting and file name expansion. When arglist is NULL, perform |
* here document expansion. |
*/ |
void |
expandarg(arg, arglist, flag) |
union node *arg; |
struct arglist *arglist; |
int flag; |
{ |
struct strlist *sp; |
char *p; |
argbackq = arg->narg.backquote; |
STARTSTACKSTR(expdest); |
ifsfirst.next = NULL; |
ifslastp = NULL; |
argstr(arg->narg.text, flag); |
if (arglist == NULL) { |
return; /* here document expanded */ |
} |
STPUTC('\0', expdest); |
p = grabstackstr(expdest); |
exparg.lastp = &exparg.list; |
/* |
* TODO - EXP_REDIR |
*/ |
if (flag & EXP_FULL) { |
ifsbreakup(p, &exparg); |
*exparg.lastp = NULL; |
exparg.lastp = &exparg.list; |
expandmeta(exparg.list, flag); |
} else { |
if (flag & EXP_REDIR) /*XXX - for now, just remove escapes */ |
rmescapes(p); |
sp = (struct strlist *)stalloc(sizeof (struct strlist)); |
sp->text = p; |
*exparg.lastp = sp; |
exparg.lastp = &sp->next; |
} |
ifsfree(); |
*exparg.lastp = NULL; |
if (exparg.list) { |
*arglist->lastp = exparg.list; |
arglist->lastp = exparg.lastp; |
} |
} |
/* |
* Perform variable and command substitution. If EXP_FULL is set, output CTLESC |
* characters to allow for further processing. Otherwise treat |
* $@ like $* since no splitting will be performed. |
*/ |
STATIC void |
argstr(p, flag) |
char *p; |
int flag; |
{ |
char c; |
int quotes = flag & (EXP_FULL | EXP_CASE); /* do CTLESC */ |
int firsteq = 1; |
if (*p == '~' && (flag & (EXP_TILDE | EXP_VARTILDE))) |
p = exptilde(p, flag); |
for (;;) { |
switch (c = *p++) { |
case '\0': |
case CTLENDVAR: /* ??? */ |
goto breakloop; |
case CTLQUOTEMARK: |
/* "$@" syntax adherence hack */ |
if (p[0] == CTLVAR && p[2] == '@' && p[3] == '=') |
break; |
if ((flag & EXP_FULL) != 0) |
STPUTC(c, expdest); |
break; |
case CTLESC: |
if (quotes) |
STPUTC(c, expdest); |
c = *p++; |
STPUTC(c, expdest); |
break; |
case CTLVAR: |
p = evalvar(p, flag); |
break; |
case CTLBACKQ: |
case CTLBACKQ|CTLQUOTE: |
expbackq(argbackq->n, c & CTLQUOTE, flag); |
argbackq = argbackq->next; |
break; |
case CTLENDARI: |
expari(flag); |
break; |
case ':': |
case '=': |
/* |
* sort of a hack - expand tildes in variable |
* assignments (after the first '=' and after ':'s). |
*/ |
STPUTC(c, expdest); |
if (flag & EXP_VARTILDE && *p == '~') { |
if (c == '=') { |
if (firsteq) |
firsteq = 0; |
else |
break; |
} |
p = exptilde(p, flag); |
} |
break; |
default: |
STPUTC(c, expdest); |
} |
} |
breakloop:; |
return; |
} |
STATIC char * |
exptilde(p, flag) |
char *p; |
int flag; |
{ |
char c, *startp = p; |
struct passwd *pw; |
const char *home; |
int quotes = flag & (EXP_FULL | EXP_CASE); |
while ((c = *p) != '\0') { |
switch(c) { |
case CTLESC: |
return (startp); |
case CTLQUOTEMARK: |
return (startp); |
case ':': |
if (flag & EXP_VARTILDE) |
goto done; |
break; |
case '/': |
goto done; |
} |
p++; |
} |
done: |
*p = '\0'; |
if (*(startp+1) == '\0') { |
if ((home = lookupvar("HOME")) == NULL) |
goto lose; |
} else { |
if ((pw = getpwnam(startp+1)) == NULL) |
goto lose; |
home = pw->pw_dir; |
} |
if (*home == '\0') |
goto lose; |
*p = c; |
while ((c = *home++) != '\0') { |
if (quotes && SQSYNTAX[(int)c] == CCTL) |
STPUTC(CTLESC, expdest); |
STPUTC(c, expdest); |
} |
return (p); |
lose: |
*p = c; |
return (startp); |
} |
STATIC void |
removerecordregions(endoff) |
int endoff; |
{ |
if (ifslastp == NULL) |
return; |
if (ifsfirst.endoff > endoff) { |
while (ifsfirst.next != NULL) { |
struct ifsregion *ifsp; |
INTOFF; |
ifsp = ifsfirst.next->next; |
ckfree(ifsfirst.next); |
ifsfirst.next = ifsp; |
INTON; |
} |
if (ifsfirst.begoff > endoff) |
ifslastp = NULL; |
else { |
ifslastp = &ifsfirst; |
ifsfirst.endoff = endoff; |
} |
return; |
} |
ifslastp = &ifsfirst; |
while (ifslastp->next && ifslastp->next->begoff < endoff) |
ifslastp=ifslastp->next; |
while (ifslastp->next != NULL) { |
struct ifsregion *ifsp; |
INTOFF; |
ifsp = ifslastp->next->next; |
ckfree(ifslastp->next); |
ifslastp->next = ifsp; |
INTON; |
} |
if (ifslastp->endoff > endoff) |
ifslastp->endoff = endoff; |
} |
/* |
* Expand arithmetic expression. Backup to start of expression, |
* evaluate, place result in (backed up) result, adjust string position. |
*/ |
void |
expari(flag) |
int flag; |
{ |
char *p, *start; |
int result; |
int begoff; |
int quotes = flag & (EXP_FULL | EXP_CASE); |
int quoted; |
/* ifsfree(); */ |
/* |
* This routine is slightly over-complicated for |
* efficiency. First we make sure there is |
* enough space for the result, which may be bigger |
* than the expression if we add exponentation. Next we |
* scan backwards looking for the start of arithmetic. If the |
* next previous character is a CTLESC character, then we |
* have to rescan starting from the beginning since CTLESC |
* characters have to be processed left to right. |
*/ |
CHECKSTRSPACE(10, expdest); |
USTPUTC('\0', expdest); |
start = stackblock(); |
p = expdest - 1; |
while (*p != CTLARI && p >= start) |
--p; |
if (*p != CTLARI) |
error("missing CTLARI (shouldn't happen)"); |
if (p > start && *(p-1) == CTLESC) |
for (p = start; *p != CTLARI; p++) |
if (*p == CTLESC) |
p++; |
if (p[1] == '"') |
quoted=1; |
else |
quoted=0; |
begoff = p - start; |
removerecordregions(begoff); |
if (quotes) |
rmescapes(p+2); |
result = arith(p+2); |
fmtstr(p, 12, "%d", result); |
while (*p++) |
; |
if (quoted == 0) |
recordregion(begoff, p - 1 - start, 0); |
result = expdest - p + 1; |
STADJUST(-result, expdest); |
} |
/* |
* Expand stuff in backwards quotes. |
*/ |
STATIC void |
expbackq(cmd, quoted, flag) |
union node *cmd; |
int quoted; |
int flag; |
{ |
struct backcmd in; |
int i; |
char buf[128]; |
char *p; |
char *dest = expdest; |
struct ifsregion saveifs, *savelastp; |
struct nodelist *saveargbackq; |
char lastc; |
int startloc = dest - stackblock(); |
char const *syntax = quoted? DQSYNTAX : BASESYNTAX; |
int saveherefd; |
int quotes = flag & (EXP_FULL | EXP_CASE); |
INTOFF; |
saveifs = ifsfirst; |
savelastp = ifslastp; |
saveargbackq = argbackq; |
saveherefd = herefd; |
herefd = -1; |
p = grabstackstr(dest); |
evalbackcmd(cmd, &in); |
ungrabstackstr(p, dest); |
ifsfirst = saveifs; |
ifslastp = savelastp; |
argbackq = saveargbackq; |
herefd = saveherefd; |
p = in.buf; |
lastc = '\0'; |
for (;;) { |
if (--in.nleft < 0) { |
if (in.fd < 0) |
break; |
while ((i = read(in.fd, buf, sizeof buf)) < 0 && errno == EINTR); |
TRACE(("expbackq: read returns %d\n", i)); |
if (i <= 0) |
break; |
p = buf; |
in.nleft = i - 1; |
} |
lastc = *p++; |
if (lastc != '\0') { |
if (quotes && syntax[(int)lastc] == CCTL) |
STPUTC(CTLESC, dest); |
STPUTC(lastc, dest); |
} |
} |
/* Eat all trailing newlines */ |
for (p--; lastc == '\n'; lastc = *--p) |
STUNPUTC(dest); |
if (in.fd >= 0) |
close(in.fd); |
if (in.buf) |
ckfree(in.buf); |
if (in.jp) |
exitstatus = waitforjob(in.jp); |
if (quoted == 0) |
recordregion(startloc, dest - stackblock(), 0); |
TRACE(("evalbackq: size=%d: \"%.*s\"\n", |
(dest - stackblock()) - startloc, |
(dest - stackblock()) - startloc, |
stackblock() + startloc)); |
expdest = dest; |
INTON; |
} |
STATIC int |
subevalvar(p, str, strloc, subtype, startloc, varflags) |
char *p; |
char *str; |
int strloc; |
int subtype; |
int startloc; |
int varflags; |
{ |
char *startp; |
char *loc = NULL; |
char *q; |
int c = 0; |
int saveherefd = herefd; |
struct nodelist *saveargbackq = argbackq; |
int amount; |
herefd = -1; |
argstr(p, subtype != VSASSIGN && subtype != VSQUESTION ? EXP_CASE : 0); |
STACKSTRNUL(expdest); |
herefd = saveherefd; |
argbackq = saveargbackq; |
startp = stackblock() + startloc; |
if (str == NULL) |
str = stackblock() + strloc; |
switch (subtype) { |
case VSASSIGN: |
setvar(str, startp, 0); |
amount = startp - expdest; |
STADJUST(amount, expdest); |
varflags &= ~VSNUL; |
if (c != 0) |
*loc = c; |
return 1; |
case VSQUESTION: |
if (*p != CTLENDVAR) { |
outfmt(&errout, "%s\n", startp); |
error((char *)NULL); |
} |
error("%.*s: parameter %snot set", p - str - 1, |
str, (varflags & VSNUL) ? "null or " |
: nullstr); |
/* NOTREACHED */ |
case VSTRIMLEFT: |
for (loc = startp; loc < str; loc++) { |
c = *loc; |
*loc = '\0'; |
if (patmatch2(str, startp, varflags & VSQUOTE)) |
goto recordleft; |
*loc = c; |
if ((varflags & VSQUOTE) && *loc == CTLESC) |
loc++; |
} |
return 0; |
case VSTRIMLEFTMAX: |
for (loc = str - 1; loc >= startp;) { |
c = *loc; |
*loc = '\0'; |
if (patmatch2(str, startp, varflags & VSQUOTE)) |
goto recordleft; |
*loc = c; |
loc--; |
if ((varflags & VSQUOTE) && loc > startp && |
*(loc - 1) == CTLESC) { |
for (q = startp; q < loc; q++) |
if (*q == CTLESC) |
q++; |
if (q > loc) |
loc--; |
} |
} |
return 0; |
case VSTRIMRIGHT: |
for (loc = str - 1; loc >= startp;) { |
if (patmatch2(str, loc, varflags & VSQUOTE)) |
goto recordright; |
loc--; |
if ((varflags & VSQUOTE) && loc > startp && |
*(loc - 1) == CTLESC) { |
for (q = startp; q < loc; q++) |
if (*q == CTLESC) |
q++; |
if (q > loc) |
loc--; |
} |
} |
return 0; |
case VSTRIMRIGHTMAX: |
for (loc = startp; loc < str - 1; loc++) { |
if (patmatch2(str, loc, varflags & VSQUOTE)) |
goto recordright; |
if ((varflags & VSQUOTE) && *loc == CTLESC) |
loc++; |
} |
return 0; |
default: |
abort(); |
} |
recordleft: |
*loc = c; |
amount = ((str - 1) - (loc - startp)) - expdest; |
STADJUST(amount, expdest); |
while (loc != str - 1) |
*startp++ = *loc++; |
return 1; |
recordright: |
amount = loc - expdest; |
STADJUST(amount, expdest); |
STPUTC('\0', expdest); |
STADJUST(-1, expdest); |
return 1; |
} |
/* |
* Expand a variable, and return a pointer to the next character in the |
* input string. |
*/ |
STATIC char * |
evalvar(p, flag) |
char *p; |
int flag; |
{ |
int subtype; |
int varflags; |
char *var; |
char *val; |
int patloc; |
int c; |
int set; |
int special; |
int startloc; |
int varlen; |
int easy; |
int quotes = flag & (EXP_FULL | EXP_CASE); |
varflags = *p++; |
subtype = varflags & VSTYPE; |
var = p; |
special = 0; |
if (! is_name(*p)) |
special = 1; |
p = strchr(p, '=') + 1; |
again: /* jump here after setting a variable with ${var=text} */ |
if (special) { |
set = varisset(var, varflags & VSNUL); |
val = NULL; |
} else { |
val = lookupvar(var); |
if (val == NULL || ((varflags & VSNUL) && val[0] == '\0')) { |
val = NULL; |
set = 0; |
} else |
set = 1; |
} |
varlen = 0; |
startloc = expdest - stackblock(); |
if (set && subtype != VSPLUS) { |
/* insert the value of the variable */ |
if (special) { |
varvalue(var, varflags & VSQUOTE, flag & EXP_FULL); |
if (subtype == VSLENGTH) { |
varlen = expdest - stackblock() - startloc; |
STADJUST(-varlen, expdest); |
} |
} else { |
char const *syntax = (varflags & VSQUOTE) ? DQSYNTAX |
: BASESYNTAX; |
if (subtype == VSLENGTH) { |
for (;*val; val++) |
varlen++; |
} |
else { |
while (*val) { |
if (quotes && syntax[(int)*val] == CCTL) |
STPUTC(CTLESC, expdest); |
STPUTC(*val++, expdest); |
} |
} |
} |
} |
if (subtype == VSPLUS) |
set = ! set; |
easy = ((varflags & VSQUOTE) == 0 || |
(*var == '@' && shellparam.nparam != 1)); |
switch (subtype) { |
case VSLENGTH: |
expdest = cvtnum(varlen, expdest); |
goto record; |
case VSNORMAL: |
if (!easy) |
break; |
record: |
recordregion(startloc, expdest - stackblock(), |
varflags & VSQUOTE); |
break; |
case VSPLUS: |
case VSMINUS: |
if (!set) { |
argstr(p, flag); |
break; |
} |
if (easy) |
goto record; |
break; |
case VSTRIMLEFT: |
case VSTRIMLEFTMAX: |
case VSTRIMRIGHT: |
case VSTRIMRIGHTMAX: |
if (!set) |
break; |
/* |
* Terminate the string and start recording the pattern |
* right after it |
*/ |
STPUTC('\0', expdest); |
patloc = expdest - stackblock(); |
if (subevalvar(p, NULL, patloc, subtype, |
startloc, varflags) == 0) { |
int amount = (expdest - stackblock() - patloc) + 1; |
STADJUST(-amount, expdest); |
} |
/* Remove any recorded regions beyond start of variable */ |
removerecordregions(startloc); |
goto record; |
case VSASSIGN: |
case VSQUESTION: |
if (!set) { |
if (subevalvar(p, var, 0, subtype, startloc, |
varflags)) { |
varflags &= ~VSNUL; |
/* |
* Remove any recorded regions beyond |
* start of variable |
*/ |
removerecordregions(startloc); |
goto again; |
} |
break; |
} |
if (easy) |
goto record; |
break; |
default: |
abort(); |
} |
if (subtype != VSNORMAL) { /* skip to end of alternative */ |
int nesting = 1; |
for (;;) { |
if ((c = *p++) == CTLESC) |
p++; |
else if (c == CTLBACKQ || c == (CTLBACKQ|CTLQUOTE)) { |
if (set) |
argbackq = argbackq->next; |
} else if (c == CTLVAR) { |
if ((*p++ & VSTYPE) != VSNORMAL) |
nesting++; |
} else if (c == CTLENDVAR) { |
if (--nesting == 0) |
break; |
} |
} |
} |
return p; |
} |
/* |
* Test whether a specialized variable is set. |
*/ |
STATIC int |
varisset(name, nulok) |
char *name; |
int nulok; |
{ |
if (*name == '!') |
return backgndpid != -1; |
else if (*name == '@' || *name == '*') { |
if (*shellparam.p == NULL) |
return 0; |
if (nulok) { |
char **av; |
for (av = shellparam.p; *av; av++) |
if (**av != '\0') |
return 1; |
return 0; |
} |
} else if (is_digit(*name)) { |
char *ap; |
int num = atoi(name); |
if (num > shellparam.nparam) |
return 0; |
if (num == 0) |
ap = arg0; |
else |
ap = shellparam.p[num - 1]; |
if (nulok && (ap == NULL || *ap == '\0')) |
return 0; |
} |
return 1; |
} |
/* |
* Put a string on the stack. |
*/ |
STATIC char * |
strtodest(p, quoted, allow_split) |
char *p; |
int quoted; |
int allow_split; |
{ |
char const *syntax; |
if (allow_split) { |
syntax = quoted ? DQSYNTAX : BASESYNTAX; |
while (*p) { |
if (syntax[(int) *p] == CCTL) |
STPUTC(CTLESC, expdest); |
STPUTC(*p++, expdest); |
} |
} else |
while (*p) |
STPUTC(*p++, expdest); |
return p; |
} |
/* |
* Add the value of a specialized variable to the stack string. |
*/ |
STATIC void |
varvalue(name, quoted, allow_split) |
char *name; |
int quoted; |
int allow_split; |
{ |
int num; |
char *p; |
int i; |
extern int oexitstatus; |
char sep; |
char **ap; |
switch (*name) { |
case '$': |
num = rootpid; |
goto numvar; |
case '?': |
num = oexitstatus; |
goto numvar; |
case '#': |
num = shellparam.nparam; |
goto numvar; |
case '!': |
num = backgndpid; |
numvar: |
expdest = cvtnum(num, expdest); |
break; |
case '-': |
for (i = 0 ; i < NOPTS ; i++) { |
if (optlist[i].val) |
STPUTC(optlist[i].letter, expdest); |
} |
break; |
case '@': |
if (allow_split && quoted) { |
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { |
p = strtodest(p, quoted, allow_split); |
if (*ap) |
STPUTC('\0', expdest); |
} |
break; |
} |
/* fall through */ |
case '*': |
if (ifsset() != 0) |
sep = ifsval()[0]; |
else |
sep = ' '; |
for (ap = shellparam.p ; (p = *ap++) != NULL ; ) { |
p = strtodest(p, quoted, allow_split); |
if (*ap && sep) |
STPUTC(sep, expdest); |
} |
break; |
case '0': |
p = strtodest(arg0, quoted, allow_split); |
break; |
default: |
if (is_digit(*name)) { |
num = atoi(name); |
if (num > 0 && num <= shellparam.nparam) { |
p = strtodest(shellparam.p[num - 1], quoted, |
allow_split); |
} |
} |
break; |
} |
} |
/* |
* Record the fact that we have to scan this region of the |
* string for IFS characters. |
*/ |
STATIC void |
recordregion(start, end, nulonly) |
int start; |
int end; |
int nulonly; |
{ |
struct ifsregion *ifsp; |
if (ifslastp == NULL) { |
ifsp = &ifsfirst; |
} else { |
ifsp = (struct ifsregion *)ckmalloc(sizeof (struct ifsregion)); |
ifslastp->next = ifsp; |
} |
ifslastp = ifsp; |
ifslastp->next = NULL; |
ifslastp->begoff = start; |
ifslastp->endoff = end; |
ifslastp->nulonly = nulonly; |
} |
/* |
* Break the argument string into pieces based upon IFS and add the |
* strings to the argument list. The regions of the string to be |
* searched for IFS characters have been stored by recordregion. |
*/ |
STATIC void |
ifsbreakup(string, arglist) |
char *string; |
struct arglist *arglist; |
{ |
struct ifsregion *ifsp; |
struct strlist *sp; |
char *start; |
char *p; |
char *q; |
const char *ifs; |
int ifsspc; |
int nulonly; |
start = string; |
ifsspc = 0; |
nulonly = 0; |
if (ifslastp != NULL) { |
ifsp = &ifsfirst; |
do { |
p = string + ifsp->begoff; |
nulonly = ifsp->nulonly; |
ifs = nulonly ? nullstr : |
( ifsset() ? ifsval() : " \t\n" ); |
ifsspc = 0; |
while (p < string + ifsp->endoff) { |
q = p; |
if (*p == CTLESC) |
p++; |
if (strchr(ifs, *p)) { |
if (!nulonly) |
ifsspc = (strchr(" \t\n", *p) != NULL); |
/* Ignore IFS whitespace at start */ |
if (q == start && ifsspc) { |
p++; |
start = p; |
continue; |
} |
*q = '\0'; |
sp = (struct strlist *)stalloc(sizeof *sp); |
sp->text = start; |
*arglist->lastp = sp; |
arglist->lastp = &sp->next; |
p++; |
if (!nulonly) { |
for (;;) { |
if (p >= string + ifsp->endoff) { |
break; |
} |
q = p; |
if (*p == CTLESC) |
p++; |
if (strchr(ifs, *p) == NULL ) { |
p = q; |
break; |
} else if (strchr(" \t\n",*p) == NULL) { |
if (ifsspc) { |
p++; |
ifsspc = 0; |
} else { |
p = q; |
break; |
} |
} else |
p++; |
} |
} |
start = p; |
} else |
p++; |
} |
} while ((ifsp = ifsp->next) != NULL); |
if (*start || (!ifsspc && start > string && |
(nulonly || 1))) { |
sp = (struct strlist *)stalloc(sizeof *sp); |
sp->text = start; |
*arglist->lastp = sp; |
arglist->lastp = &sp->next; |
} |
} else { |
sp = (struct strlist *)stalloc(sizeof *sp); |
sp->text = start; |
*arglist->lastp = sp; |
arglist->lastp = &sp->next; |
} |
} |
STATIC void |
ifsfree() |
{ |
while (ifsfirst.next != NULL) { |
struct ifsregion *ifsp; |
INTOFF; |
ifsp = ifsfirst.next->next; |
ckfree(ifsfirst.next); |
ifsfirst.next = ifsp; |
INTON; |
} |
ifslastp = NULL; |
ifsfirst.next = NULL; |
} |
/* |
* Expand shell metacharacters. At this point, the only control characters |
* should be escapes. The results are stored in the list exparg. |
*/ |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
STATIC void |
expandmeta(str, flag) |
struct strlist *str; |
int flag; |
{ |
const char *p; |
glob_t pglob; |
/* TODO - EXP_REDIR */ |
while (str) { |
if (fflag) |
goto nometa; |
p = preglob(str->text); |
INTOFF; |
switch (glob(p, GLOB_NOMAGIC, 0, &pglob)) { |
case 0: |
if (!(pglob.gl_flags & GLOB_MAGCHAR)) |
goto nometa2; |
addglob(&pglob); |
globfree(&pglob); |
INTON; |
break; |
case GLOB_NOMATCH: |
nometa2: |
globfree(&pglob); |
INTON; |
nometa: |
*exparg.lastp = str; |
rmescapes(str->text); |
exparg.lastp = &str->next; |
break; |
default: /* GLOB_NOSPACE */ |
error("Out of space"); |
} |
str = str->next; |
} |
} |
/* |
* Prepare the string for glob(3). |
*/ |
STATIC const char * |
preglob(str) |
const char *str; |
{ |
const char *p; |
char *q, *r; |
size_t len; |
p = str; |
while (*p != CTLQUOTEMARK && *p != CTLESC) { |
if (*p++ == '\0') |
return str; |
} |
len = p - str; |
q = r = stalloc(strlen(str) + 1); |
if (len > 0) { |
memcpy(q, str, len); |
q += len; |
} |
do { |
if (*p == CTLQUOTEMARK) |
continue; |
if (*p == CTLESC) { |
if (*++p != '/') |
*q++ = '\\'; |
} |
*q++ = *p; |
} while (*++p); |
*q = '\0'; |
return r; |
} |
/* |
* Add the result of glob(3) to the list. |
*/ |
STATIC void |
addglob(pglob) |
const glob_t *pglob; |
{ |
char **p = pglob->gl_pathv; |
do { |
addfname(*p); |
} while (*++p); |
} |
#else |
char *expdir; |
STATIC void |
expandmeta(str, flag) |
struct strlist *str; |
int flag; |
{ |
char *p; |
struct strlist **savelastp; |
struct strlist *sp; |
char c; |
/* TODO - EXP_REDIR */ |
while (str) { |
if (fflag) |
goto nometa; |
p = str->text; |
for (;;) { /* fast check for meta chars */ |
if ((c = *p++) == '\0') |
goto nometa; |
if (c == '*' || c == '?' || c == '[' || c == '!') |
break; |
} |
savelastp = exparg.lastp; |
INTOFF; |
if (expdir == NULL) { |
int i = strlen(str->text); |
expdir = ckmalloc(i < 2048 ? 2048 : i); /* XXX */ |
} |
expmeta(expdir, str->text); |
ckfree(expdir); |
expdir = NULL; |
INTON; |
if (exparg.lastp == savelastp) { |
/* |
* no matches |
*/ |
nometa: |
*exparg.lastp = str; |
rmescapes(str->text); |
exparg.lastp = &str->next; |
} else { |
*exparg.lastp = NULL; |
*savelastp = sp = expsort(*savelastp); |
while (sp->next != NULL) |
sp = sp->next; |
exparg.lastp = &sp->next; |
} |
str = str->next; |
} |
} |
/* |
* Do metacharacter (i.e. *, ?, [...]) expansion. |
*/ |
STATIC void |
expmeta(enddir, name) |
char *enddir; |
char *name; |
{ |
char *p; |
const char *cp; |
char *q; |
char *start; |
char *endname; |
int metaflag; |
struct stat statb; |
DIR *dirp; |
struct dirent *dp; |
int atend; |
int matchdot; |
metaflag = 0; |
start = name; |
for (p = name ; ; p++) { |
if (*p == '*' || *p == '?') |
metaflag = 1; |
else if (*p == '[') { |
q = p + 1; |
if (*q == '!') |
q++; |
for (;;) { |
while (*q == CTLQUOTEMARK) |
q++; |
if (*q == CTLESC) |
q++; |
if (*q == '/' || *q == '\0') |
break; |
if (*++q == ']') { |
metaflag = 1; |
break; |
} |
} |
} else if (*p == '!' && p[1] == '!' && (p == name || p[-1] == '/')) { |
metaflag = 1; |
} else if (*p == '\0') |
break; |
else if (*p == CTLQUOTEMARK) |
continue; |
else if (*p == CTLESC) |
p++; |
if (*p == '/') { |
if (metaflag) |
break; |
start = p + 1; |
} |
} |
if (metaflag == 0) { /* we've reached the end of the file name */ |
if (enddir != expdir) |
metaflag++; |
for (p = name ; ; p++) { |
if (*p == CTLQUOTEMARK) |
continue; |
if (*p == CTLESC) |
p++; |
*enddir++ = *p; |
if (*p == '\0') |
break; |
} |
if (metaflag == 0 || stat(expdir, &statb) >= 0) |
addfname(expdir); |
return; |
} |
endname = p; |
if (start != name) { |
p = name; |
while (p < start) { |
while (*p == CTLQUOTEMARK) |
p++; |
if (*p == CTLESC) |
p++; |
*enddir++ = *p++; |
} |
} |
if (enddir == expdir) { |
cp = "."; |
} else if (enddir == expdir + 1 && *expdir == '/') { |
cp = "/"; |
} else { |
cp = expdir; |
enddir[-1] = '\0'; |
} |
if ((dirp = opendir(cp)) == NULL) |
return; |
if (enddir != expdir) |
enddir[-1] = '/'; |
if (*endname == 0) { |
atend = 1; |
} else { |
atend = 0; |
*endname++ = '\0'; |
} |
matchdot = 0; |
p = start; |
while (*p == CTLQUOTEMARK) |
p++; |
if (*p == CTLESC) |
p++; |
if (*p == '.') |
matchdot++; |
while (! int_pending() && (dp = readdir(dirp)) != NULL) { |
if (dp->d_name[0] == '.' && ! matchdot) |
continue; |
if (patmatch(start, dp->d_name, 0)) { |
if (atend) { |
scopy(dp->d_name, enddir); |
addfname(expdir); |
} else { |
for (p = enddir, cp = dp->d_name; |
(*p++ = *cp++) != '\0';) |
continue; |
p[-1] = '/'; |
expmeta(p, endname); |
} |
} |
} |
closedir(dirp); |
if (! atend) |
endname[-1] = '/'; |
} |
#endif |
/* |
* Add a file name to the list. |
*/ |
STATIC void |
addfname(name) |
char *name; |
{ |
char *p; |
struct strlist *sp; |
p = stalloc(strlen(name) + 1); |
scopy(name, p); |
sp = (struct strlist *)stalloc(sizeof *sp); |
sp->text = p; |
*exparg.lastp = sp; |
exparg.lastp = &sp->next; |
} |
#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) |
/* |
* Sort the results of file name expansion. It calculates the number of |
* strings to sort and then calls msort (short for merge sort) to do the |
* work. |
*/ |
STATIC struct strlist * |
expsort(str) |
struct strlist *str; |
{ |
int len; |
struct strlist *sp; |
len = 0; |
for (sp = str ; sp ; sp = sp->next) |
len++; |
return msort(str, len); |
} |
STATIC struct strlist * |
msort(list, len) |
struct strlist *list; |
int len; |
{ |
struct strlist *p, *q = NULL; |
struct strlist **lpp; |
int half; |
int n; |
if (len <= 1) |
return list; |
half = len >> 1; |
p = list; |
for (n = half ; --n >= 0 ; ) { |
q = p; |
p = p->next; |
} |
q->next = NULL; /* terminate first half of list */ |
q = msort(list, half); /* sort first half of list */ |
p = msort(p, len - half); /* sort second half */ |
lpp = &list; |
for (;;) { |
if (strcmp(p->text, q->text) < 0) { |
*lpp = p; |
lpp = &p->next; |
if ((p = *lpp) == NULL) { |
*lpp = q; |
break; |
} |
} else { |
*lpp = q; |
lpp = &q->next; |
if ((q = *lpp) == NULL) { |
*lpp = p; |
break; |
} |
} |
} |
return list; |
} |
#endif |
/* |
* Returns true if the pattern matches the string. |
*/ |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
STATIC int |
patmatch(pattern, string, squoted) |
char *pattern; |
char *string; |
int squoted; /* string might have quote chars */ |
{ |
const char *p; |
char *q; |
p = preglob(pattern); |
q = squoted ? _rmescapes(string, 1) : string; |
return !fnmatch(p, q, 0); |
} |
STATIC int |
patmatch2(pattern, string, squoted) |
char *pattern; |
char *string; |
int squoted; /* string might have quote chars */ |
{ |
char *p; |
int res; |
sstrnleft--; |
p = grabstackstr(expdest); |
res = patmatch(pattern, string, squoted); |
ungrabstackstr(p, expdest); |
return res; |
} |
#else |
int |
patmatch(pattern, string, squoted) |
char *pattern; |
char *string; |
int squoted; /* string might have quote chars */ |
{ |
#ifdef notdef |
if (pattern[0] == '!' && pattern[1] == '!') |
return 1 - pmatch(pattern + 2, string); |
else |
#endif |
return pmatch(pattern, string, squoted); |
} |
STATIC int |
pmatch(pattern, string, squoted) |
char *pattern; |
char *string; |
int squoted; |
{ |
char *p, *q; |
char c; |
p = pattern; |
q = string; |
for (;;) { |
switch (c = *p++) { |
case '\0': |
goto breakloop; |
case CTLESC: |
if (squoted && *q == CTLESC) |
q++; |
if (*q++ != *p++) |
return 0; |
break; |
case CTLQUOTEMARK: |
continue; |
case '?': |
if (squoted && *q == CTLESC) |
q++; |
if (*q++ == '\0') |
return 0; |
break; |
case '*': |
c = *p; |
while (c == CTLQUOTEMARK || c == '*') |
c = *++p; |
if (c != CTLESC && c != CTLQUOTEMARK && |
c != '?' && c != '*' && c != '[') { |
while (*q != c) { |
if (squoted && *q == CTLESC && |
q[1] == c) |
break; |
if (*q == '\0') |
return 0; |
if (squoted && *q == CTLESC) |
q++; |
q++; |
} |
} |
do { |
if (pmatch(p, q, squoted)) |
return 1; |
if (squoted && *q == CTLESC) |
q++; |
} while (*q++ != '\0'); |
return 0; |
case '[': { |
char *endp; |
int invert, found; |
char chr; |
endp = p; |
if (*endp == '!') |
endp++; |
for (;;) { |
while (*endp == CTLQUOTEMARK) |
endp++; |
if (*endp == '\0') |
goto dft; /* no matching ] */ |
if (*endp == CTLESC) |
endp++; |
if (*++endp == ']') |
break; |
} |
invert = 0; |
if (*p == '!') { |
invert++; |
p++; |
} |
found = 0; |
chr = *q++; |
if (squoted && chr == CTLESC) |
chr = *q++; |
if (chr == '\0') |
return 0; |
c = *p++; |
do { |
if (c == CTLQUOTEMARK) |
continue; |
if (c == CTLESC) |
c = *p++; |
if (*p == '-' && p[1] != ']') { |
p++; |
while (*p == CTLQUOTEMARK) |
p++; |
if (*p == CTLESC) |
p++; |
if (chr >= c && chr <= *p) |
found = 1; |
p++; |
} else { |
if (chr == c) |
found = 1; |
} |
} while ((c = *p++) != ']'); |
if (found == invert) |
return 0; |
break; |
} |
dft: default: |
if (squoted && *q == CTLESC) |
q++; |
if (*q++ != c) |
return 0; |
break; |
} |
} |
breakloop: |
if (*q != '\0') |
return 0; |
return 1; |
} |
#endif |
/* |
* Remove any CTLESC characters from a string. |
*/ |
#if defined(__GLIBC__) && !defined(GLOB_BROKEN) |
void |
rmescapes(str) |
char *str; |
{ |
_rmescapes(str, 0); |
} |
STATIC char * |
_rmescapes(str, flag) |
char *str; |
int flag; |
{ |
char *p, *q, *r; |
p = str; |
while (*p != CTLESC && *p != CTLQUOTEMARK) { |
if (*p++ == '\0') |
return str; |
} |
q = p; |
r = str; |
if (flag) { |
size_t len = p - str; |
q = r = stalloc(strlen(p) + len + 1); |
if (len > 0) { |
memcpy(q, str, len); |
q += len; |
} |
} |
while (*p) { |
if (*p == CTLQUOTEMARK) { |
p++; |
continue; |
} |
if (*p == CTLESC) |
p++; |
*q++ = *p++; |
} |
*q = '\0'; |
return r; |
} |
#else |
void |
rmescapes(str) |
char *str; |
{ |
char *p, *q; |
p = str; |
while (*p != CTLESC && *p != CTLQUOTEMARK) { |
if (*p++ == '\0') |
return; |
} |
q = p; |
while (*p) { |
if (*p == CTLQUOTEMARK) { |
p++; |
continue; |
} |
if (*p == CTLESC) |
p++; |
*q++ = *p++; |
} |
*q = '\0'; |
} |
#endif |
/* |
* See if a pattern matches in a case statement. |
*/ |
int |
casematch(pattern, val) |
union node *pattern; |
char *val; |
{ |
struct stackmark smark; |
int result; |
char *p; |
setstackmark(&smark); |
argbackq = pattern->narg.backquote; |
STARTSTACKSTR(expdest); |
ifslastp = NULL; |
argstr(pattern->narg.text, EXP_TILDE | EXP_CASE); |
STPUTC('\0', expdest); |
p = grabstackstr(expdest); |
result = patmatch(p, val, 0); |
popstackmark(&smark); |
return result; |
} |
/* |
* Our own itoa(). |
*/ |
STATIC char * |
cvtnum(num, buf) |
int num; |
char *buf; |
{ |
char temp[32]; |
int neg = num < 0; |
char *p = temp + 31; |
temp[31] = '\0'; |
do { |
*--p = num % 10 + '0'; |
} while ((num /= 10) != 0); |
if (neg) |
*--p = '-'; |
while (*p) |
STPUTC(*p++, buf); |
return buf; |
} |
/branches/dd/uspace/app/ash/mail.c |
---|
0,0 → 1,125 |
/* $NetBSD: mail.c,v 1.14 2000/07/03 03:26:19 matt Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)mail.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: mail.c,v 1.14 2000/07/03 03:26:19 matt Exp $"); |
#endif |
#endif /* not lint */ |
/* |
* Routines to check for mail. (Perhaps make part of main.c?) |
*/ |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <stdlib.h> |
#include "shell.h" |
#include "exec.h" /* defines padvance() */ |
#include "var.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "mail.h" |
#define MAXMBOXES 10 |
STATIC int nmboxes; /* number of mailboxes */ |
STATIC time_t mailtime[MAXMBOXES]; /* times of mailboxes */ |
/* |
* Print appropriate message(s) if mail has arrived. If the argument is |
* nozero, then the value of MAIL has changed, so we just update the |
* values. |
*/ |
void |
chkmail(silent) |
int silent; |
{ |
int i; |
const char *mpath; |
char *p; |
char *q; |
struct stackmark smark; |
struct stat statb; |
if (silent) |
nmboxes = 10; |
if (nmboxes == 0) |
return; |
setstackmark(&smark); |
mpath = mpathset()? mpathval() : mailval(); |
for (i = 0 ; i < nmboxes ; i++) { |
p = padvance(&mpath, nullstr); |
if (p == NULL) |
break; |
if (*p == '\0') |
continue; |
for (q = p ; *q ; q++); |
if (q[-1] != '/') |
abort(); |
q[-1] = '\0'; /* delete trailing '/' */ |
#ifdef notdef /* this is what the System V shell claims to do (it lies) */ |
if (stat(p, &statb) < 0) |
statb.st_mtime = 0; |
if (statb.st_mtime > mailtime[i] && ! silent) { |
out2str(pathopt? pathopt : "you have mail"); |
out2c('\n'); |
} |
mailtime[i] = statb.st_mtime; |
#else /* this is what it should do */ |
if (stat(p, &statb) < 0) |
statb.st_size = 0; |
if (statb.st_size > mailtime[i] && ! silent) { |
out2str(pathopt? pathopt : "you have mail"); |
out2c('\n'); |
} |
mailtime[i] = statb.st_size; |
#endif |
} |
nmboxes = i; |
popstackmark(&smark); |
} |
/branches/dd/uspace/app/ash/miscbltin.c |
---|
0,0 → 1,422 |
/* $NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)miscbltin.c 8.4 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: miscbltin.c,v 1.29 2001/01/04 15:39:51 lukem Exp $"); |
#endif |
#endif /* not lint */ |
/* |
* Miscelaneous builtins. |
*/ |
#include <sys/types.h> /* quad_t */ |
#include <sys/param.h> /* BSD4_4 */ |
#include <sys/stat.h> |
#include <sys/time.h> |
#include <sys/resource.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include <ctype.h> |
#include <errno.h> |
#include "shell.h" |
#include "options.h" |
#include "var.h" |
#include "output.h" |
#include "memalloc.h" |
#include "error.h" |
#include "miscbltin.h" |
#include "mystring.h" |
#undef rflag |
#ifdef __GLIBC__ |
mode_t getmode(const void *, mode_t); |
void *setmode(const char *); |
#if !defined(__GLIBC__) || __GLIBC__ == 2 && __GLIBC_MINOR__ < 1 |
typedef enum __rlimit_resource rlim_t; |
#endif |
#endif |
extern char **argptr; /* argument list for builtin command */ |
/* |
* The read builtin. The -e option causes backslashes to escape the |
* following character. |
* |
* This uses unbuffered input, which may be avoidable in some cases. |
*/ |
int |
readcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char **ap; |
int backslash; |
char c; |
int rflag; |
char *prompt; |
char *ifs; |
char *p; |
int startword; |
int status; |
int i; |
rflag = 0; |
prompt = NULL; |
while ((i = nextopt("p:r")) != '\0') { |
if (i == 'p') |
prompt = optarg; |
else |
rflag = 1; |
} |
if (prompt && isatty(0)) { |
out2str(prompt); |
flushall(); |
} |
if (*(ap = argptr) == NULL) |
error("arg count"); |
if ((ifs = bltinlookup("IFS", 1)) == NULL) |
ifs = nullstr; |
status = 0; |
startword = 1; |
backslash = 0; |
STARTSTACKSTR(p); |
for (;;) { |
if (read(0, &c, 1) != 1) { |
status = 1; |
break; |
} |
if (c == '\0') |
continue; |
if (backslash) { |
backslash = 0; |
if (c != '\n') |
STPUTC(c, p); |
continue; |
} |
if (!rflag && c == '\\') { |
backslash++; |
continue; |
} |
if (c == '\n') |
break; |
if (startword && *ifs == ' ' && strchr(ifs, c)) { |
continue; |
} |
startword = 0; |
if (backslash && c == '\\') { |
if (read(0, &c, 1) != 1) { |
status = 1; |
break; |
} |
STPUTC(c, p); |
} else if (ap[1] != NULL && strchr(ifs, c) != NULL) { |
STACKSTRNUL(p); |
setvar(*ap, stackblock(), 0); |
ap++; |
startword = 1; |
STARTSTACKSTR(p); |
} else { |
STPUTC(c, p); |
} |
} |
STACKSTRNUL(p); |
/* Remove trailing blanks */ |
while (stackblock() <= --p && strchr(ifs, *p) != NULL) |
*p = '\0'; |
setvar(*ap, stackblock(), 0); |
while (*++ap != NULL) |
setvar(*ap, nullstr, 0); |
return status; |
} |
int |
umaskcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char *ap; |
int mask; |
int i; |
int symbolic_mode = 0; |
while ((i = nextopt("S")) != '\0') { |
symbolic_mode = 1; |
} |
INTOFF; |
mask = umask(0); |
umask(mask); |
INTON; |
if ((ap = *argptr) == NULL) { |
if (symbolic_mode) { |
char u[4], g[4], o[4]; |
i = 0; |
if ((mask & S_IRUSR) == 0) |
u[i++] = 'r'; |
if ((mask & S_IWUSR) == 0) |
u[i++] = 'w'; |
if ((mask & S_IXUSR) == 0) |
u[i++] = 'x'; |
u[i] = '\0'; |
i = 0; |
if ((mask & S_IRGRP) == 0) |
g[i++] = 'r'; |
if ((mask & S_IWGRP) == 0) |
g[i++] = 'w'; |
if ((mask & S_IXGRP) == 0) |
g[i++] = 'x'; |
g[i] = '\0'; |
i = 0; |
if ((mask & S_IROTH) == 0) |
o[i++] = 'r'; |
if ((mask & S_IWOTH) == 0) |
o[i++] = 'w'; |
if ((mask & S_IXOTH) == 0) |
o[i++] = 'x'; |
o[i] = '\0'; |
out1fmt("u=%s,g=%s,o=%s\n", u, g, o); |
} else { |
out1fmt("%.4o\n", mask); |
} |
} else { |
if (isdigit((unsigned char)*ap)) { |
mask = 0; |
do { |
if (*ap >= '8' || *ap < '0') |
error("Illegal number: %s", argv[1]); |
mask = (mask << 3) + (*ap - '0'); |
} while (*++ap != '\0'); |
umask(mask); |
} else { |
void *set; |
INTOFF; |
if ((set = setmode(ap)) != 0) { |
mask = getmode(set, ~mask & 0777); |
ckfree(set); |
} |
INTON; |
if (!set) |
error("Illegal mode: %s", ap); |
umask(~mask & 0777); |
} |
} |
return 0; |
} |
/* |
* ulimit builtin |
* |
* This code, originally by Doug Gwyn, Doug Kingston, Eric Gisin, and |
* Michael Rendell was ripped from pdksh 5.0.8 and hacked for use with |
* ash by J.T. Conklin. |
* |
* Public domain. |
*/ |
struct limits { |
const char *name; |
int cmd; |
int factor; /* multiply by to get rlim_{cur,max} values */ |
char option; |
}; |
static const struct limits limits[] = { |
#ifdef RLIMIT_CPU |
{ "time(seconds)", RLIMIT_CPU, 1, 't' }, |
#endif |
#ifdef RLIMIT_FSIZE |
{ "file(blocks)", RLIMIT_FSIZE, 512, 'f' }, |
#endif |
#ifdef RLIMIT_DATA |
{ "data(kbytes)", RLIMIT_DATA, 1024, 'd' }, |
#endif |
#ifdef RLIMIT_STACK |
{ "stack(kbytes)", RLIMIT_STACK, 1024, 's' }, |
#endif |
#ifdef RLIMIT_CORE |
{ "coredump(blocks)", RLIMIT_CORE, 512, 'c' }, |
#endif |
#ifdef RLIMIT_RSS |
{ "memory(kbytes)", RLIMIT_RSS, 1024, 'm' }, |
#endif |
#ifdef RLIMIT_MEMLOCK |
{ "locked memory(kbytes)", RLIMIT_MEMLOCK, 1024, 'l' }, |
#endif |
#ifdef RLIMIT_NPROC |
{ "process(processes)", RLIMIT_NPROC, 1, 'p' }, |
#endif |
#ifdef RLIMIT_NOFILE |
{ "nofiles(descriptors)", RLIMIT_NOFILE, 1, 'n' }, |
#endif |
#ifdef RLIMIT_VMEM |
{ "vmemory(kbytes)", RLIMIT_VMEM, 1024, 'v' }, |
#endif |
#ifdef RLIMIT_SWAP |
{ "swap(kbytes)", RLIMIT_SWAP, 1024, 'w' }, |
#endif |
{ (char *) 0, 0, 0, '\0' } |
}; |
int |
ulimitcmd(argc, argv) |
int argc; |
char **argv; |
{ |
int c; |
rlim_t val = 0; |
enum { SOFT = 0x1, HARD = 0x2 } |
how = SOFT | HARD; |
const struct limits *l; |
int set, all = 0; |
int optc, what; |
struct rlimit limit; |
what = 'f'; |
while ((optc = nextopt("HSatfdsmcnpl")) != '\0') |
switch (optc) { |
case 'H': |
how = HARD; |
break; |
case 'S': |
how = SOFT; |
break; |
case 'a': |
all = 1; |
break; |
default: |
what = optc; |
} |
for (l = limits; l->name && l->option != what; l++) |
; |
if (!l->name) |
error("internal error (%c)", what); |
set = *argptr ? 1 : 0; |
if (set) { |
char *p = *argptr; |
if (all || argptr[1]) |
error("too many arguments"); |
if (strcmp(p, "unlimited") == 0) |
val = RLIM_INFINITY; |
else { |
val = (rlim_t) 0; |
while ((c = *p++) >= '0' && c <= '9') |
{ |
val = (val * 10) + (long)(c - '0'); |
if (val < (rlim_t) 0) |
break; |
} |
if (c) |
error("bad number"); |
val *= l->factor; |
} |
} |
if (all) { |
for (l = limits; l->name; l++) { |
getrlimit(l->cmd, &limit); |
if (how & SOFT) |
val = limit.rlim_cur; |
else if (how & HARD) |
val = limit.rlim_max; |
out1fmt("%-20s ", l->name); |
if (val == RLIM_INFINITY) |
out1fmt("unlimited\n"); |
else |
{ |
val /= l->factor; |
#ifdef BSD4_4 |
out1fmt("%lld\n", (long long) val); |
#else |
out1fmt("%ld\n", (long) val); |
#endif |
} |
} |
return 0; |
} |
getrlimit(l->cmd, &limit); |
if (set) { |
if (how & HARD) |
limit.rlim_max = val; |
if (how & SOFT) |
limit.rlim_cur = val; |
if (setrlimit(l->cmd, &limit) < 0) |
error("error setting limit (%s)", strerror(errno)); |
} else { |
if (how & SOFT) |
val = limit.rlim_cur; |
else if (how & HARD) |
val = limit.rlim_max; |
if (val == RLIM_INFINITY) |
out1fmt("unlimited\n"); |
else |
{ |
val /= l->factor; |
#ifdef BSD4_4 |
out1fmt("%lld\n", (long long) val); |
#else |
out1fmt("%ld\n", (long) val); |
#endif |
} |
} |
return 0; |
} |
/branches/dd/uspace/app/ash/main.c |
---|
0,0 → 1,432 |
/* $NetBSD: main.c,v 1.39 2000/11/01 19:56:01 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
__COPYRIGHT("@(#) Copyright (c) 1991, 1993\n\ |
The Regents of the University of California. All rights reserved.\n"); |
#endif /* not lint */ |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)main.c 8.7 (Berkeley) 7/19/95"; |
#else |
__RCSID("$NetBSD: main.c,v 1.39 2000/11/01 19:56:01 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <errno.h> |
#include <stdio.h> |
#include <signal.h> |
#include <sys/stat.h> |
#include <unistd.h> |
#include <fcntl.h> |
#include "shell.h" |
#include "main.h" |
#include "mail.h" |
#include "options.h" |
#include "output.h" |
#include "parser.h" |
#include "nodes.h" |
#include "expand.h" |
#include "eval.h" |
#include "jobs.h" |
#include "input.h" |
#include "trap.h" |
#include "var.h" |
#include "show.h" |
#include "memalloc.h" |
#include "error.h" |
#include "init.h" |
#include "mystring.h" |
#include "exec.h" |
#include "cd.h" |
#ifdef HETIO |
#include "hetio.h" |
#endif |
#define PROFILE 0 |
int rootpid; |
int rootshell; |
STATIC union node *curcmd; |
STATIC union node *prevcmd; |
#if PROFILE |
short profile_buf[16384]; |
extern int etext(); |
#endif |
STATIC void read_profile (const char *); |
STATIC char *find_dot_file (char *); |
int main (int, char **); |
/* |
* Main routine. We initialize things, parse the arguments, execute |
* profiles if we're a login shell, and then call cmdloop to execute |
* commands. The setjmp call sets up the location to jump to when an |
* exception occurs. When an exception occurs the variable "state" |
* is used to figure out how far we had gotten. |
*/ |
int |
main(argc, argv) |
int argc; |
char **argv; |
{ |
struct jmploc jmploc; |
struct stackmark smark; |
volatile int state; |
char *shinit; |
int priviliged; |
priviliged = getuid() != geteuid() || getgid() != getegid(); |
#if PROFILE |
monitor(4, etext, profile_buf, sizeof profile_buf, 50); |
#endif |
#if defined(linux) || defined(__GNU__) |
signal(SIGCHLD, SIG_DFL); |
#endif |
state = 0; |
if (setjmp(jmploc.loc)) { |
/* |
* When a shell procedure is executed, we raise the |
* exception EXSHELLPROC to clean up before executing |
* the shell procedure. |
*/ |
switch (exception) { |
case EXSHELLPROC: |
rootpid = getpid(); |
rootshell = 1; |
minusc = NULL; |
state = 3; |
break; |
case EXEXEC: |
exitstatus = exerrno; |
break; |
case EXERROR: |
exitstatus = 2; |
break; |
default: |
break; |
} |
if (exception != EXSHELLPROC) { |
if (state == 0 || iflag == 0 || ! rootshell) |
exitshell(exitstatus); |
} |
reset(); |
if (exception == EXINT |
#if ATTY |
&& (! attyset() || equal(termval(), "emacs")) |
#endif |
) { |
out2c('\n'); |
flushout(&errout); |
} |
popstackmark(&smark); |
FORCEINTON; /* enable interrupts */ |
if (state == 1) |
goto state1; |
else if (state == 2) |
goto state2; |
else if (state == 3) |
goto state3; |
else |
goto state4; |
} |
handler = &jmploc; |
#ifdef DEBUG |
opentrace(); |
trputs("Shell args: "); trargs(argv); |
#endif |
rootpid = getpid(); |
rootshell = 1; |
init(); |
setstackmark(&smark); |
procargs(argc, argv); |
if (argv[0] && argv[0][0] == '-') { |
state = 1; |
read_profile("/etc/profile"); |
state1: |
state = 2; |
if (priviliged == 0) |
read_profile(".profile"); |
else |
read_profile("/etc/suid_profile"); |
} |
state2: |
state = 3; |
if (iflag && !priviliged) { |
if ((shinit = lookupvar("ENV")) != NULL && *shinit != '\0') { |
state = 3; |
read_profile(shinit); |
} |
} |
state3: |
state = 4; |
if (sflag == 0 || minusc) { |
static int sigs[] = { |
SIGINT, SIGQUIT, SIGHUP, |
#ifdef SIGTSTP |
SIGTSTP, |
#endif |
SIGPIPE |
}; |
#define SIGSSIZE (sizeof(sigs)/sizeof(sigs[0])) |
int i; |
for (i = 0; i < SIGSSIZE; i++) |
setsignal(sigs[i]); |
} |
if (minusc) |
evalstring(minusc, 0); |
if (sflag || minusc == NULL) { |
state4: /* XXX ??? - why isn't this before the "if" statement */ |
cmdloop(1); |
} |
#if PROFILE |
monitor(0); |
#endif |
exitshell(exitstatus); |
/* NOTREACHED */ |
} |
/* |
* Read and execute commands. "Top" is nonzero for the top level command |
* loop; it turns on prompting if the shell is interactive. |
*/ |
void |
cmdloop(top) |
int top; |
{ |
union node *n; |
struct stackmark smark; |
int inter; |
int numeof = 0; |
TRACE(("cmdloop(%d) called\n", top)); |
setstackmark(&smark); |
#ifdef HETIO |
if(iflag && top) |
hetio_init(); |
#endif |
for (;;) { |
if (pendingsigs) |
dotrap(); |
inter = 0; |
if (iflag && top) { |
inter++; |
showjobs(1); |
chkmail(0); |
flushout(&output); |
} |
n = parsecmd(inter); |
/* showtree(n); DEBUG */ |
if (n == NEOF) { |
if (!top || numeof >= 50) |
break; |
if (!stoppedjobs()) { |
if (!Iflag) |
break; |
out2str("\nUse \"exit\" to leave shell.\n"); |
} |
numeof++; |
} else if (n != NULL && nflag == 0) { |
job_warning = (job_warning == 2) ? 1 : 0; |
numeof = 0; |
evaltree(n, 0); |
} |
popstackmark(&smark); |
setstackmark(&smark); |
if (evalskip == SKIPFILE) { |
evalskip = 0; |
break; |
} |
} |
popstackmark(&smark); |
} |
/* |
* Read /etc/profile or .profile. Return on error. |
*/ |
STATIC void |
read_profile(name) |
const char *name; |
{ |
int fd; |
int xflag_set = 0; |
int vflag_set = 0; |
INTOFF; |
if ((fd = open(name, O_RDONLY)) >= 0) |
setinputfd(fd, 1); |
INTON; |
if (fd < 0) |
return; |
/* -q turns off -x and -v just when executing init files */ |
if (qflag) { |
if (xflag) |
xflag = 0, xflag_set = 1; |
if (vflag) |
vflag = 0, vflag_set = 1; |
} |
cmdloop(0); |
if (qflag) { |
if (xflag_set) |
xflag = 1; |
if (vflag_set) |
vflag = 1; |
} |
popfile(); |
} |
/* |
* Read a file containing shell functions. |
*/ |
void |
readcmdfile(name) |
char *name; |
{ |
int fd; |
INTOFF; |
if ((fd = open(name, O_RDONLY)) >= 0) |
setinputfd(fd, 1); |
else |
error("Can't open %s", name); |
INTON; |
cmdloop(0); |
popfile(); |
} |
/* |
* Take commands from a file. To be compatable we should do a path |
* search for the file, which is necessary to find sub-commands. |
*/ |
STATIC char * |
find_dot_file(basename) |
char *basename; |
{ |
char *fullname; |
const char *path = pathval(); |
struct stat statb; |
/* don't try this for absolute or relative paths */ |
if (strchr(basename, '/')) |
return basename; |
while ((fullname = padvance(&path, basename)) != NULL) { |
if ((stat(fullname, &statb) == 0) && S_ISREG(statb.st_mode)) { |
/* |
* Don't bother freeing here, since it will |
* be freed by the caller. |
*/ |
return fullname; |
} |
stunalloc(fullname); |
} |
/* not found in the PATH */ |
error("%s: not found", basename); |
/* NOTREACHED */ |
} |
int |
dotcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct strlist *sp; |
exitstatus = 0; |
for (sp = cmdenviron; sp ; sp = sp->next) |
setvareq(savestr(sp->text), VSTRFIXED|VTEXTFIXED); |
if (argc >= 2) { /* That's what SVR2 does */ |
char *fullname; |
struct stackmark smark; |
setstackmark(&smark); |
fullname = find_dot_file(argv[1]); |
setinputfile(fullname, 1); |
commandname = fullname; |
cmdloop(0); |
popfile(); |
popstackmark(&smark); |
} |
return exitstatus; |
} |
int |
exitcmd(argc, argv) |
int argc; |
char **argv; |
{ |
extern int oexitstatus; |
if (stoppedjobs()) |
return 0; |
if (argc > 1) |
exitstatus = number(argv[1]); |
else |
exitstatus = oexitstatus; |
exitshell(exitstatus); |
/* NOTREACHED */ |
} |
/branches/dd/uspace/app/ash/expand.h |
---|
0,0 → 1,77 |
/* $NetBSD: expand.h,v 1.12 1999/07/09 03:05:50 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)expand.h 8.2 (Berkeley) 5/4/95 |
*/ |
struct strlist { |
struct strlist *next; |
char *text; |
}; |
struct arglist { |
struct strlist *list; |
struct strlist **lastp; |
}; |
/* |
* expandarg() flags |
*/ |
#define EXP_FULL 0x1 /* perform word splitting & file globbing */ |
#define EXP_TILDE 0x2 /* do normal tilde expansion */ |
#define EXP_VARTILDE 0x4 /* expand tildes in an assignment */ |
#define EXP_REDIR 0x8 /* file glob for a redirection (1 match only) */ |
#define EXP_CASE 0x10 /* keeps quotes around for CASE pattern */ |
#define EXP_RECORD 0x20 /* need to record arguments for ifs breakup */ |
union node; |
void expandhere (union node *, int); |
void expandarg (union node *, struct arglist *, int); |
void expari (int); |
#if !(defined(__GLIBC__) && !defined(GLOB_BROKEN)) |
int patmatch (char *, char *, int); |
#endif |
void rmescapes (char *); |
int casematch (union node *, char *); |
/* From arith.y */ |
int arith (const char *); |
int expcmd (int , char **); |
void arith_lex_reset (void); |
int yylex (void); |
/branches/dd/uspace/app/ash/mail.h |
---|
0,0 → 1,41 |
/* $NetBSD: mail.h,v 1.8 1995/05/11 21:29:23 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)mail.h 8.2 (Berkeley) 5/4/95 |
*/ |
void chkmail (int); |
/branches/dd/uspace/app/ash/eval.c |
---|
0,0 → 1,1159 |
/* $NetBSD: eval.c,v 1.56 2000/05/22 10:18:46 elric Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)eval.c 8.9 (Berkeley) 6/8/95"; |
#else |
__RCSID("$NetBSD: eval.c,v 1.56 2000/05/22 10:18:46 elric Exp $"); |
#endif |
#endif /* not lint */ |
#include <sys/types.h> |
#include <signal.h> |
#include <malloc.h> |
#include <unistd.h> |
/* |
* Evaluate a command. |
*/ |
#include "shell.h" |
#include "nodes.h" |
#include "syntax.h" |
#include "expand.h" |
#include "parser.h" |
#include "jobs.h" |
#include "eval.h" |
#include "builtins.h" |
#include "options.h" |
#include "exec.h" |
#include "redir.h" |
#include "input.h" |
#include "output.h" |
#include "trap.h" |
#include "var.h" |
#include "memalloc.h" |
#include "error.h" |
#include "show.h" |
#include "mystring.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#endif |
/* flags in argument to evaltree */ |
#define EV_EXIT 01 /* exit after evaluating tree */ |
#define EV_TESTED 02 /* exit status is checked; ignore -e flag */ |
#define EV_BACKCMD 04 /* command executing within back quotes */ |
MKINIT int evalskip; /* set if we are skipping commands */ |
STATIC int skipcount; /* number of levels to skip */ |
MKINIT int loopnest; /* current loop nesting level */ |
int funcnest; /* depth of function calls */ |
char *commandname; |
struct strlist *cmdenviron; |
int exitstatus; /* exit status of last command */ |
int oexitstatus; /* saved exit status */ |
STATIC void evalloop (union node *, int); |
STATIC void evalfor (union node *, int); |
STATIC void evalcase (union node *, int); |
STATIC void evalsubshell (union node *, int); |
STATIC void expredir (union node *); |
STATIC void evalpipe (union node *); |
STATIC void evalcommand (union node *, int, struct backcmd *); |
STATIC void prehash (union node *); |
STATIC int is_assignment_builtin (const char *); |
STATIC const char *get_standard_path (void); |
/* |
* Called to reset things after an exception. |
*/ |
#ifdef mkinit |
INCLUDE "eval.h" |
RESET { |
evalskip = 0; |
loopnest = 0; |
funcnest = 0; |
} |
SHELLPROC { |
exitstatus = 0; |
} |
#endif |
/* |
* The eval commmand. |
*/ |
int |
evalcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char *p; |
char *concat; |
char **ap; |
if (argc > 1) { |
p = argv[1]; |
if (argc > 2) { |
STARTSTACKSTR(concat); |
ap = argv + 2; |
for (;;) { |
while (*p) |
STPUTC(*p++, concat); |
if ((p = *ap++) == NULL) |
break; |
STPUTC(' ', concat); |
} |
STPUTC('\0', concat); |
p = grabstackstr(concat); |
} |
evalstring(p, EV_TESTED); |
} |
return exitstatus; |
} |
/* |
* Execute a command or commands contained in a string. |
*/ |
void |
evalstring(s, flag) |
char *s; |
int flag; |
{ |
union node *n; |
struct stackmark smark; |
setstackmark(&smark); |
setinputstring(s, 1); |
while ((n = parsecmd(0)) != NEOF) { |
evaltree(n, flag); |
popstackmark(&smark); |
} |
popfile(); |
popstackmark(&smark); |
} |
/* |
* Evaluate a parse tree. The value is left in the global variable |
* exitstatus. |
*/ |
void |
evaltree(n, flags) |
union node *n; |
int flags; |
{ |
if (n == NULL) { |
TRACE(("evaltree(NULL) called\n")); |
exitstatus = 0; |
goto out; |
} |
#ifndef SMALL |
displayhist = 1; /* show history substitutions done with fc */ |
#endif |
TRACE(("evaltree(0x%lx: %d) called\n", (long)n, n->type)); |
switch (n->type) { |
case NSEMI: |
evaltree(n->nbinary.ch1, flags & EV_TESTED); |
if (evalskip) |
goto out; |
evaltree(n->nbinary.ch2, flags); |
break; |
case NAND: |
evaltree(n->nbinary.ch1, EV_TESTED); |
if (evalskip || exitstatus != 0) { |
/* don't bomb out on "set -e; false && true" */ |
flags |= EV_TESTED; |
goto out; |
} |
evaltree(n->nbinary.ch2, flags | EV_TESTED); |
break; |
case NOR: |
evaltree(n->nbinary.ch1, EV_TESTED); |
if (evalskip || exitstatus == 0) |
goto out; |
evaltree(n->nbinary.ch2, flags | EV_TESTED); |
break; |
case NREDIR: |
expredir(n->nredir.redirect); |
redirect(n->nredir.redirect, REDIR_PUSH); |
evaltree(n->nredir.n, flags); |
popredir(); |
break; |
case NSUBSHELL: |
evalsubshell(n, flags); |
break; |
case NBACKGND: |
evalsubshell(n, flags); |
break; |
case NIF: { |
evaltree(n->nif.test, EV_TESTED); |
if (evalskip) |
goto out; |
if (exitstatus == 0) |
evaltree(n->nif.ifpart, flags); |
else if (n->nif.elsepart) |
evaltree(n->nif.elsepart, flags); |
else |
exitstatus = 0; |
break; |
} |
case NWHILE: |
case NUNTIL: |
evalloop(n, flags); |
break; |
case NFOR: |
evalfor(n, flags); |
break; |
case NCASE: |
evalcase(n, flags); |
break; |
case NDEFUN: |
if (is_special_builtin(n->narg.text)) { |
outfmt(out2, "%s is a special built-in\n", n->narg.text); |
exitstatus = 1; |
break; |
} |
defun(n->narg.text, n->narg.next); |
exitstatus = 0; |
break; |
case NNOT: |
evaltree(n->nnot.com, EV_TESTED); |
exitstatus = !exitstatus; |
break; |
case NPIPE: |
evalpipe(n); |
break; |
case NCMD: |
evalcommand(n, flags, (struct backcmd *)NULL); |
break; |
default: |
out1fmt("Node type = %d\n", n->type); |
flushout(&output); |
break; |
} |
out: |
if (pendingsigs) |
dotrap(); |
if ((flags & EV_EXIT) || (eflag && exitstatus && !(flags & EV_TESTED))) |
exitshell(exitstatus); |
} |
STATIC void |
evalloop(n, flags) |
union node *n; |
int flags; |
{ |
int status; |
loopnest++; |
status = 0; |
for (;;) { |
evaltree(n->nbinary.ch1, EV_TESTED); |
if (evalskip) { |
skipping: if (evalskip == SKIPCONT && --skipcount <= 0) { |
evalskip = 0; |
continue; |
} |
if (evalskip == SKIPBREAK && --skipcount <= 0) |
evalskip = 0; |
break; |
} |
if (n->type == NWHILE) { |
if (exitstatus != 0) |
break; |
} else { |
if (exitstatus == 0) |
break; |
} |
evaltree(n->nbinary.ch2, flags & EV_TESTED); |
status = exitstatus; |
if (evalskip) |
goto skipping; |
} |
loopnest--; |
exitstatus = status; |
} |
STATIC void |
evalfor(n, flags) |
union node *n; |
int flags; |
{ |
struct arglist arglist; |
union node *argp; |
struct strlist *sp; |
struct stackmark smark; |
setstackmark(&smark); |
arglist.lastp = &arglist.list; |
for (argp = n->nfor.args ; argp ; argp = argp->narg.next) { |
oexitstatus = exitstatus; |
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE | EXP_RECORD); |
if (evalskip) |
goto out; |
} |
*arglist.lastp = NULL; |
exitstatus = 0; |
loopnest++; |
for (sp = arglist.list ; sp ; sp = sp->next) { |
setvar(n->nfor.var, sp->text, 0); |
evaltree(n->nfor.body, flags & EV_TESTED); |
if (evalskip) { |
if (evalskip == SKIPCONT && --skipcount <= 0) { |
evalskip = 0; |
continue; |
} |
if (evalskip == SKIPBREAK && --skipcount <= 0) |
evalskip = 0; |
break; |
} |
} |
loopnest--; |
out: |
popstackmark(&smark); |
} |
STATIC void |
evalcase(n, flags) |
union node *n; |
int flags; |
{ |
union node *cp; |
union node *patp; |
struct arglist arglist; |
struct stackmark smark; |
setstackmark(&smark); |
arglist.lastp = &arglist.list; |
oexitstatus = exitstatus; |
expandarg(n->ncase.expr, &arglist, EXP_TILDE); |
for (cp = n->ncase.cases ; cp && evalskip == 0 ; cp = cp->nclist.next) { |
for (patp = cp->nclist.pattern ; patp ; patp = patp->narg.next) { |
if (casematch(patp, arglist.list->text)) { |
if (evalskip == 0) { |
evaltree(cp->nclist.body, flags); |
} |
goto out; |
} |
} |
} |
out: |
popstackmark(&smark); |
} |
/* |
* Kick off a subshell to evaluate a tree. |
*/ |
STATIC void |
evalsubshell(n, flags) |
union node *n; |
int flags; |
{ |
struct job *jp; |
int backgnd = (n->type == NBACKGND); |
expredir(n->nredir.redirect); |
jp = makejob(n, 1); |
if (forkshell(jp, n, backgnd) == 0) { |
if (backgnd) |
flags &=~ EV_TESTED; |
redirect(n->nredir.redirect, 0); |
evaltree(n->nredir.n, flags | EV_EXIT); /* never returns */ |
} |
if (! backgnd) { |
INTOFF; |
exitstatus = waitforjob(jp); |
INTON; |
} |
} |
/* |
* Compute the names of the files in a redirection list. |
*/ |
STATIC void |
expredir(n) |
union node *n; |
{ |
union node *redir; |
for (redir = n ; redir ; redir = redir->nfile.next) { |
struct arglist fn; |
fn.lastp = &fn.list; |
oexitstatus = exitstatus; |
switch (redir->type) { |
case NFROMTO: |
case NFROM: |
case NTO: |
case NAPPEND: |
case NTOOV: |
expandarg(redir->nfile.fname, &fn, EXP_TILDE | EXP_REDIR); |
redir->nfile.expfname = fn.list->text; |
break; |
case NFROMFD: |
case NTOFD: |
if (redir->ndup.vname) { |
expandarg(redir->ndup.vname, &fn, EXP_FULL | EXP_TILDE); |
fixredir(redir, fn.list->text, 1); |
} |
break; |
} |
} |
} |
/* |
* Evaluate a pipeline. All the processes in the pipeline are children |
* of the process creating the pipeline. (This differs from some versions |
* of the shell, which make the last process in a pipeline the parent |
* of all the rest.) |
*/ |
STATIC void |
evalpipe(n) |
union node *n; |
{ |
struct job *jp; |
struct nodelist *lp; |
int pipelen; |
int prevfd; |
int pip[2]; |
TRACE(("evalpipe(0x%lx) called\n", (long)n)); |
pipelen = 0; |
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) |
pipelen++; |
INTOFF; |
jp = makejob(n, pipelen); |
prevfd = -1; |
for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) { |
prehash(lp->n); |
pip[1] = -1; |
if (lp->next) { |
if (pipe(pip) < 0) { |
close(prevfd); |
error("Pipe call failed"); |
} |
} |
if (forkshell(jp, lp->n, n->npipe.backgnd) == 0) { |
INTON; |
if (prevfd > 0) { |
close(0); |
copyfd(prevfd, 0); |
close(prevfd); |
if (pip[0] == 0) { |
pip[0] = -1; |
} |
} |
if (pip[1] >= 0) { |
if (pip[0] >= 0) { |
close(pip[0]); |
} |
if (pip[1] != 1) { |
close(1); |
copyfd(pip[1], 1); |
close(pip[1]); |
} |
} |
evaltree(lp->n, EV_EXIT); |
} |
if (prevfd >= 0) |
close(prevfd); |
prevfd = pip[0]; |
close(pip[1]); |
} |
INTON; |
if (n->npipe.backgnd == 0) { |
INTOFF; |
exitstatus = waitforjob(jp); |
TRACE(("evalpipe: job done exit status %d\n", exitstatus)); |
INTON; |
} |
} |
/* |
* Execute a command inside back quotes. If it's a builtin command, we |
* want to save its output in a block obtained from malloc. Otherwise |
* we fork off a subprocess and get the output of the command via a pipe. |
* Should be called with interrupts off. |
*/ |
void |
evalbackcmd(n, result) |
union node *n; |
struct backcmd *result; |
{ |
int pip[2]; |
struct job *jp; |
struct stackmark smark; /* unnecessary */ |
setstackmark(&smark); |
result->fd = -1; |
result->buf = NULL; |
result->nleft = 0; |
result->jp = NULL; |
if (n == NULL) { |
exitstatus = 0; |
goto out; |
} |
#ifdef notyet |
/* |
* For now we disable executing builtins in the same |
* context as the shell, because we are not keeping |
* enough state to recover from changes that are |
* supposed only to affect subshells. eg. echo "`cd /`" |
*/ |
if (n->type == NCMD) { |
exitstatus = oexitstatus; |
evalcommand(n, EV_BACKCMD, result); |
} else |
#endif |
{ |
exitstatus = 0; |
if (pipe(pip) < 0) |
error("Pipe call failed"); |
jp = makejob(n, 1); |
if (forkshell(jp, n, FORK_NOJOB) == 0) { |
FORCEINTON; |
close(pip[0]); |
if (pip[1] != 1) { |
close(1); |
copyfd(pip[1], 1); |
close(pip[1]); |
} |
eflag = 0; |
evaltree(n, EV_EXIT); |
} |
close(pip[1]); |
result->fd = pip[0]; |
result->jp = jp; |
} |
out: |
popstackmark(&smark); |
TRACE(("evalbackcmd done: fd=%d buf=0x%x nleft=%d jp=0x%x\n", |
result->fd, result->buf, result->nleft, result->jp)); |
} |
/* |
* Execute a simple command. |
*/ |
STATIC void |
evalcommand(cmd, flags, backcmd) |
union node *cmd; |
int flags; |
struct backcmd *backcmd; |
{ |
struct stackmark smark; |
union node *argp; |
struct arglist arglist; |
struct arglist varlist; |
char **argv; |
int argc; |
char **envp; |
int varflag; |
int pseudovarflag; |
struct strlist *sp; |
int mode; |
int pip[2]; |
struct cmdentry cmdentry; |
struct job *jp; |
struct jmploc jmploc; |
struct jmploc *volatile savehandler; |
char *volatile savecmdname; |
volatile struct shparam saveparam; |
struct localvar *volatile savelocalvars; |
volatile int e; |
char *lastarg; |
int not_special; |
const char *path; |
const char *standard_path; |
#if __GNUC__ |
/* Avoid longjmp clobbering */ |
(void) &argv; |
(void) &argc; |
(void) &lastarg; |
(void) &flags; |
(void) ¬_special; |
(void) &standard_path; |
#endif |
/* First expand the arguments. */ |
TRACE(("evalcommand(0x%lx, %d) called\n", (long)cmd, flags)); |
setstackmark(&smark); |
arglist.lastp = &arglist.list; |
varlist.lastp = &varlist.list; |
arglist.list = 0; |
varflag = 1; |
pseudovarflag = 0; |
oexitstatus = exitstatus; |
exitstatus = 0; |
not_special = 0; |
path = pathval(); |
standard_path = NULL; |
for (argp = cmd->ncmd.args ; argp ; argp = argp->narg.next) { |
char *p = argp->narg.text; |
if ((varflag || pseudovarflag) && is_name(*p)) { |
do { |
p++; |
} while (is_in_name(*p)); |
if (*p == '=') { |
if (varflag) |
expandarg(argp, &varlist, EXP_VARTILDE); |
else |
expandarg(argp, &arglist, EXP_VARTILDE); |
continue; |
} |
} |
expandarg(argp, &arglist, EXP_FULL | EXP_TILDE); |
if (varflag && arglist.list && is_assignment_builtin(arglist.list->text)) |
pseudovarflag = 1; |
varflag = 0; |
} |
*arglist.lastp = NULL; |
*varlist.lastp = NULL; |
expredir(cmd->ncmd.redirect); |
argc = 0; |
for (sp = arglist.list ; sp ; sp = sp->next) |
argc++; |
argv = stalloc(sizeof (char *) * (argc + 1)); |
for (sp = arglist.list ; sp ; sp = sp->next) { |
TRACE(("evalcommand arg: %s\n", sp->text)); |
*argv++ = sp->text; |
} |
*argv = NULL; |
lastarg = NULL; |
if (iflag && funcnest == 0 && argc > 0) |
lastarg = argv[-1]; |
argv -= argc; |
/* Print the command if xflag is set. */ |
if (xflag) { |
outc('+', &errout); |
for (sp = varlist.list ; sp ; sp = sp->next) { |
outc(' ', &errout); |
out2str(sp->text); |
} |
for (sp = arglist.list ; sp ; sp = sp->next) { |
outc(' ', &errout); |
out2str(sp->text); |
} |
outc('\n', &errout); |
flushout(&errout); |
} |
/* Now locate the command. */ |
if (argc == 0) { |
cmdentry.cmdtype = CMDBUILTIN; |
cmdentry.u.index = BLTINCMD; |
} else { |
static const char PATH[] = "PATH="; |
const char *oldpath = NULL; |
int findflag = DO_ERR; |
/* |
* Modify the command lookup path, if a PATH= assignment |
* is present |
*/ |
for (sp = varlist.list ; sp ; sp = sp->next) |
if (strncmp(sp->text, PATH, sizeof(PATH) - 1) == 0) { |
path = sp->text + sizeof(PATH) - 1; |
findflag |= DO_BRUTE; |
} |
for(;;) { |
find_command(argv[0], &cmdentry, findflag, path); |
if (oldpath) { |
path = oldpath; |
oldpath = NULL; |
} |
if (cmdentry.cmdtype == CMDUNKNOWN) { /* command not found */ |
exitstatus = 127; |
flushout(&errout); |
goto out; |
} |
/* implement the bltin builtin here */ |
if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == BLTINCMD) { |
not_special = 1; |
for(;;) { |
argv++; |
if (--argc == 0) |
break; |
if ((cmdentry.u.index = find_builtin(*argv)) < 0) { |
outfmt(&errout, "%s: not found\n", *argv); |
exitstatus = 127; |
flushout(&errout); |
goto out; |
} |
if (cmdentry.u.index != BLTINCMD) |
break; |
} |
} |
if (cmdentry.cmdtype == CMDBUILTIN && cmdentry.u.index == COMMANDCMD) { |
not_special = 1; |
argv++; |
if (--argc == 0) { |
exitstatus = 0; |
goto out; |
} |
if (*argv[0] == '-') { |
if (!equal(argv[0], "-p")) { |
argv--; |
argc++; |
break; |
} |
argv++; |
if (--argc == 0) { |
exitstatus = 0; |
goto out; |
} |
if (!standard_path) { |
standard_path = get_standard_path(); |
} |
oldpath = path; |
path = standard_path; |
findflag |= DO_BRUTE; |
} |
findflag |= DO_NOFUN; |
continue; |
} |
break; |
} |
} |
/* Fork off a child process if necessary. */ |
if (cmd->ncmd.backgnd |
|| (cmdentry.cmdtype == CMDNORMAL && (flags & EV_EXIT) == 0) |
|| ((flags & EV_BACKCMD) != 0 |
&& (cmdentry.cmdtype != CMDBUILTIN |
|| cmdentry.u.index == DOTCMD |
|| cmdentry.u.index == EVALCMD))) { |
jp = makejob(cmd, 1); |
mode = cmd->ncmd.backgnd; |
if (flags & EV_BACKCMD) { |
mode = FORK_NOJOB; |
if (pipe(pip) < 0) |
error("Pipe call failed"); |
} |
if (forkshell(jp, cmd, mode) != 0) |
goto parent; /* at end of routine */ |
if (flags & EV_BACKCMD) { |
FORCEINTON; |
close(pip[0]); |
if (pip[1] != 1) { |
close(1); |
copyfd(pip[1], 1); |
close(pip[1]); |
} |
} |
flags |= EV_EXIT; |
} |
/* This is the child process if a fork occurred. */ |
/* Execute the command. */ |
if (cmdentry.cmdtype == CMDFUNCTION) { |
#ifdef DEBUG |
trputs("Shell function: "); trargs(argv); |
#endif |
exitstatus = oexitstatus; |
redirect(cmd->ncmd.redirect, REDIR_PUSH); |
saveparam = shellparam; |
shellparam.malloc = 0; |
shellparam.nparam = argc - 1; |
shellparam.p = argv + 1; |
INTOFF; |
savelocalvars = localvars; |
localvars = NULL; |
INTON; |
if (setjmp(jmploc.loc)) { |
if (exception == EXSHELLPROC) { |
freeparam((volatile struct shparam *) |
&saveparam); |
} else { |
saveparam.optind = shellparam.optind; |
saveparam.optoff = shellparam.optoff; |
freeparam(&shellparam); |
shellparam = saveparam; |
} |
poplocalvars(); |
localvars = savelocalvars; |
handler = savehandler; |
longjmp(handler->loc, 1); |
} |
savehandler = handler; |
handler = &jmploc; |
for (sp = varlist.list ; sp ; sp = sp->next) |
mklocal(sp->text); |
funcnest++; |
evaltree(cmdentry.u.func, flags & EV_TESTED); |
funcnest--; |
INTOFF; |
poplocalvars(); |
localvars = savelocalvars; |
saveparam.optind = shellparam.optind; |
saveparam.optoff = shellparam.optoff; |
freeparam(&shellparam); |
shellparam = saveparam; |
handler = savehandler; |
popredir(); |
INTON; |
if (evalskip == SKIPFUNC) { |
evalskip = 0; |
skipcount = 0; |
} |
if (flags & EV_EXIT) |
exitshell(exitstatus); |
} else if (cmdentry.cmdtype == CMDBUILTIN) { |
#ifdef DEBUG |
trputs("builtin command: "); trargs(argv); |
#endif |
mode = (cmdentry.u.index == EXECCMD)? 0 : REDIR_PUSH; |
if (flags == EV_BACKCMD) { |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
openmemout(); |
#else |
memout.nleft = 0; |
memout.nextc = memout.buf; |
memout.bufsize = 64; |
#endif |
mode |= REDIR_BACKQ; |
} |
redirect(cmd->ncmd.redirect, mode); |
savecmdname = commandname; |
cmdenviron = varlist.list; |
e = -1; |
if (setjmp(jmploc.loc)) { |
e = exception; |
exitstatus = (e == EXINT)? SIGINT+128 : 2; |
goto cmddone; |
} |
savehandler = handler; |
handler = &jmploc; |
commandname = argv[0]; |
argptr = argv + 1; |
optptr = NULL; /* initialize nextopt */ |
exitstatus = (*builtinfunc[cmdentry.u.index])(argc, argv); |
flushall(); |
cmddone: |
out1 = &output; |
out2 = &errout; |
freestdout(); |
if (!not_special && is_special_builtin(commandname)) |
listsetvar(cmdenviron); |
cmdenviron = NULL; |
if (e != EXSHELLPROC) { |
commandname = savecmdname; |
if (flags & EV_EXIT) |
exitshell(exitstatus); |
} |
handler = savehandler; |
if (e != -1) { |
if ((e != EXERROR && e != EXEXEC) |
|| cmdentry.u.index == BLTINCMD |
|| cmdentry.u.index == DOTCMD |
|| cmdentry.u.index == EVALCMD |
#ifndef SMALL |
|| cmdentry.u.index == HISTCMD |
#endif |
|| cmdentry.u.index == EXECCMD) |
exraise(e); |
FORCEINTON; |
} |
if (cmdentry.u.index != EXECCMD) |
popredir(); |
if (flags == EV_BACKCMD) { |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
closememout(); |
#endif |
backcmd->buf = memout.buf; |
#if defined(_GNU_SOURCE) && !defined(__UCLIBC__) |
backcmd->nleft = memout.bufsize; |
#else |
backcmd->nleft = memout.nextc - memout.buf; |
#endif |
memout.buf = NULL; |
} |
cmdenviron = NULL; |
} else { |
#ifdef DEBUG |
trputs("normal command: "); trargs(argv); |
#endif |
clearredir(); |
redirect(cmd->ncmd.redirect, 0); |
for (sp = varlist.list ; sp ; sp = sp->next) |
setvareq(sp->text, VEXPORT|VSTACK); |
envp = environment(); |
shellexec(argv, envp, path, cmdentry.u.index); |
} |
goto out; |
parent: /* parent process gets here (if we forked) */ |
if (mode == 0) { /* argument to fork */ |
INTOFF; |
exitstatus = waitforjob(jp); |
INTON; |
} else if (mode == 2) { |
backcmd->fd = pip[0]; |
close(pip[1]); |
backcmd->jp = jp; |
} |
out: |
if (lastarg) |
setvar("_", lastarg, 0); |
popstackmark(&smark); |
if (eflag && exitstatus && !(flags & EV_TESTED)) |
exitshell(exitstatus); |
} |
/* |
* Search for a command. This is called before we fork so that the |
* location of the command will be available in the parent as well as |
* the child. The check for "goodname" is an overly conservative |
* check that the name will not be subject to expansion. |
*/ |
STATIC void |
prehash(n) |
union node *n; |
{ |
struct cmdentry entry; |
if (n->type == NCMD && n->ncmd.args) |
if (goodname(n->ncmd.args->narg.text)) |
find_command(n->ncmd.args->narg.text, &entry, 0, |
pathval()); |
} |
/* |
* Builtin commands. Builtin commands whose functions are closely |
* tied to evaluation are implemented here. |
*/ |
/* |
* No command given, or a bltin command with no arguments. Set the |
* specified variables. |
*/ |
int |
bltincmd(argc, argv) |
int argc; |
char **argv; |
{ |
listsetvar(cmdenviron); |
/* |
* Preserve exitstatus of a previous possible redirection |
* as POSIX mandates |
*/ |
return exitstatus; |
} |
/* |
* Handle break and continue commands. Break, continue, and return are |
* all handled by setting the evalskip flag. The evaluation routines |
* above all check this flag, and if it is set they start skipping |
* commands rather than executing them. The variable skipcount is |
* the number of loops to break/continue, or the number of function |
* levels to return. (The latter is always 1.) It should probably |
* be an error to break out of more loops than exist, but it isn't |
* in the standard shell so we don't make it one here. |
*/ |
int |
breakcmd(argc, argv) |
int argc; |
char **argv; |
{ |
int n = argc > 1 ? number(argv[1]) : 1; |
if (n > loopnest) |
n = loopnest; |
if (n > 0) { |
evalskip = (**argv == 'c')? SKIPCONT : SKIPBREAK; |
skipcount = n; |
} |
return 0; |
} |
/* |
* The return command. |
*/ |
int |
returncmd(argc, argv) |
int argc; |
char **argv; |
{ |
int ret = argc > 1 ? number(argv[1]) : oexitstatus; |
if (funcnest) { |
evalskip = SKIPFUNC; |
skipcount = 1; |
return ret; |
} |
else { |
/* Do what ksh does; skip the rest of the file */ |
evalskip = SKIPFILE; |
skipcount = 1; |
return ret; |
} |
} |
int |
falsecmd(argc, argv) |
int argc; |
char **argv; |
{ |
return 1; |
} |
int |
truecmd(argc, argv) |
int argc; |
char **argv; |
{ |
return 0; |
} |
int |
execcmd(argc, argv) |
int argc; |
char **argv; |
{ |
if (argc > 1) { |
struct strlist *sp; |
iflag = 0; /* exit on error */ |
mflag = 0; |
optschanged(); |
for (sp = cmdenviron; sp ; sp = sp->next) |
setvareq(sp->text, VEXPORT|VSTACK); |
shellexec(argv + 1, environment(), pathval(), 0); |
} |
return 0; |
} |
STATIC int |
is_assignment_builtin (command) |
const char *command; |
{ |
static const char *assignment_builtins[] = { |
"alias", "declare", "export", "local", "readonly", "typeset", |
(char *)NULL |
}; |
int i; |
for (i = 0; assignment_builtins[i]; i++) |
if (strcmp(command, assignment_builtins[i]) == 0) return 1; |
return 0; |
} |
int |
is_special_builtin(name) |
const char *name; |
{ |
static const char *special_builtins[] = { |
"break", ":", ".", "continue", "eval", "exec", "exit", |
"export", "readonly", "return", "set", "shift", "times", |
"trap", "unset", (char *)NULL |
}; |
int i; |
if (!name) return 0; |
for (i = 0; special_builtins[i]; i++) |
if (equal(name, special_builtins[i])) return 1; |
return 0; |
} |
STATIC const char * |
get_standard_path() |
{ |
char *p; |
size_t len; |
len = confstr(_CS_PATH, NULL, 0); |
p = stalloc(len + 2); |
*p = '\0'; |
confstr(_CS_PATH, p, len); |
return p; |
} |
/branches/dd/uspace/app/ash/var.c |
---|
0,0 → 1,777 |
/* $NetBSD: var.c,v 1.26 2000/12/20 00:15:10 cgd Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)var.c 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: var.c,v 1.26 2000/12/20 00:15:10 cgd Exp $"); |
#endif |
#endif /* not lint */ |
#include <unistd.h> |
#include <stdlib.h> |
#include <paths.h> |
/* |
* Shell variables. |
*/ |
#include "shell.h" |
#include "output.h" |
#include "expand.h" |
#include "nodes.h" /* for other headers */ |
#include "eval.h" /* defines cmdenviron */ |
#include "exec.h" |
#include "syntax.h" |
#include "options.h" |
#include "mail.h" |
#include "var.h" |
#include "memalloc.h" |
#include "error.h" |
#include "mystring.h" |
#include "parser.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#endif |
#define VTABSIZE 39 |
struct varinit { |
struct var *var; |
int flags; |
const char *text; |
void (*func) (const char *); |
}; |
#if ATTY |
struct var vatty; |
#endif |
#ifndef SMALL |
struct var vhistsize; |
struct var vterm; |
#endif |
struct var vifs; |
struct var vmail; |
struct var vmpath; |
struct var vpath; |
struct var vps1; |
struct var vps2; |
struct var vvers; |
struct var voptind; |
const struct varinit varinit[] = { |
#if ATTY |
{ &vatty, VSTRFIXED|VTEXTFIXED|VUNSET, "ATTY=", |
NULL }, |
#endif |
#ifndef SMALL |
{ &vhistsize, VSTRFIXED|VTEXTFIXED|VUNSET, "HISTSIZE=", |
sethistsize }, |
#endif |
{ &vifs, VSTRFIXED|VTEXTFIXED, "IFS= \t\n", |
NULL }, |
{ &vmail, VSTRFIXED|VTEXTFIXED|VUNSET, "MAIL=", |
NULL }, |
{ &vmpath, VSTRFIXED|VTEXTFIXED|VUNSET, "MAILPATH=", |
NULL }, |
{ &vpath, VSTRFIXED|VTEXTFIXED, "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", |
changepath }, |
/* |
* vps1 depends on uid |
*/ |
{ &vps2, VSTRFIXED|VTEXTFIXED, "PS2=> ", |
NULL }, |
#ifndef SMALL |
{ &vterm, VSTRFIXED|VTEXTFIXED|VUNSET, "TERM=", |
setterm }, |
#endif |
{ &voptind, VSTRFIXED|VTEXTFIXED, "OPTIND=1", |
getoptsreset }, |
{ NULL, 0, NULL, |
NULL } |
}; |
struct var *vartab[VTABSIZE]; |
STATIC struct var **hashvar (const char *); |
STATIC int varequal (const char *, const char *); |
/* |
* Initialize the varable symbol tables and import the environment |
* Setting PWD added by herbert |
*/ |
#ifdef mkinit |
INCLUDE "cd.h" |
INCLUDE "var.h" |
INIT { |
char **envp; |
extern char **environ; |
extern char *curdir; |
initvar(); |
for (envp = environ ; *envp ; envp++) { |
if (strchr(*envp, '=')) { |
setvareq(*envp, VEXPORT|VTEXTFIXED); |
} |
} |
getpwd(); |
setvar("PWD", curdir, VEXPORT|VTEXTFIXED); |
} |
#endif |
/* |
* This routine initializes the builtin variables. It is called when the |
* shell is initialized and again when a shell procedure is spawned. |
*/ |
void |
initvar() { |
const struct varinit *ip; |
struct var *vp; |
struct var **vpp; |
char ppid[30]; |
for (ip = varinit ; (vp = ip->var) != NULL ; ip++) { |
if ((vp->flags & VEXPORT) == 0) { |
vpp = hashvar(ip->text); |
vp->next = *vpp; |
*vpp = vp; |
vp->text = strdup(ip->text); |
vp->flags = ip->flags; |
vp->func = ip->func; |
} |
} |
/* |
* PS1 depends on uid |
*/ |
if ((vps1.flags & VEXPORT) == 0) { |
vpp = hashvar("PS1="); |
vps1.next = *vpp; |
*vpp = &vps1; |
vps1.text = strdup(geteuid() ? "PS1=$ " : "PS1=# "); |
vps1.flags = VSTRFIXED|VTEXTFIXED; |
} |
snprintf(ppid, 29, "%ld", (long)getppid()); |
setvar("PPID", ppid, VREADONLY|VNOFUNC); |
} |
/* |
* Safe version of setvar, returns 1 on success 0 on failure. |
*/ |
int |
setvarsafe(name, val, flags) |
const char *name, *val; |
int flags; |
{ |
struct jmploc jmploc; |
struct jmploc *volatile savehandler = handler; |
int err = 0; |
#ifdef __GNUC__ |
(void) &err; |
#endif |
if (setjmp(jmploc.loc)) |
err = 1; |
else { |
handler = &jmploc; |
setvar(name, val, flags); |
} |
handler = savehandler; |
return err; |
} |
/* |
* Set the value of a variable. The flags argument is ored with the |
* flags of the variable. If val is NULL, the variable is unset. |
*/ |
void |
setvar(name, val, flags) |
const char *name, *val; |
int flags; |
{ |
const char *p; |
const char *q; |
char *d; |
int len; |
int namelen; |
char *nameeq; |
int isbad; |
isbad = 0; |
p = name; |
if (! is_name(*p)) |
isbad = 1; |
p++; |
for (;;) { |
if (! is_in_name(*p)) { |
if (*p == '\0' || *p == '=') |
break; |
isbad = 1; |
} |
p++; |
} |
namelen = p - name; |
if (isbad) |
error("%.*s: bad variable name", namelen, name); |
len = namelen + 2; /* 2 is space for '=' and '\0' */ |
if (val == NULL) { |
flags |= VUNSET; |
} else { |
len += strlen(val); |
} |
d = nameeq = ckmalloc(len); |
q = name; |
while (--namelen >= 0) |
*d++ = *q++; |
*d++ = '='; |
*d = '\0'; |
if (val) |
scopy(val, d); |
setvareq(nameeq, flags); |
} |
/* |
* Same as setvar except that the variable and value are passed in |
* the first argument as name=value. Since the first argument will |
* be actually stored in the table, it should not be a string that |
* will go away. |
*/ |
void |
setvareq(s, flags) |
char *s; |
int flags; |
{ |
struct var *vp, **vpp; |
vpp = hashvar(s); |
flags |= (VEXPORT & (((unsigned) (1 - aflag)) - 1)); |
for (vp = *vpp ; vp ; vp = vp->next) { |
if (varequal(s, vp->text)) { |
if (vp->flags & VREADONLY) { |
size_t len = strchr(s, '=') - s; |
error("%.*s: is read only", len, s); |
} |
INTOFF; |
if (vp->func && (flags & VNOFUNC) == 0) |
(*vp->func)(strchr(s, '=') + 1); |
if ((vp->flags & (VTEXTFIXED|VSTACK)) == 0) |
ckfree(vp->text); |
vp->flags &= ~(VTEXTFIXED|VSTACK|VUNSET); |
vp->flags |= flags; |
vp->text = s; |
/* |
* We could roll this to a function, to handle it as |
* a regular variable function callback, but why bother? |
*/ |
if (iflag && |
(vp == &vmpath || (vp == &vmail && ! mpathset()))) |
chkmail(1); |
INTON; |
return; |
} |
} |
/* not found */ |
vp = ckmalloc(sizeof (*vp)); |
vp->flags = flags; |
vp->text = s; |
vp->next = *vpp; |
vp->func = NULL; |
*vpp = vp; |
} |
/* |
* Process a linked list of variable assignments. |
*/ |
void |
listsetvar(list) |
struct strlist *list; |
{ |
struct strlist *lp; |
INTOFF; |
for (lp = list ; lp ; lp = lp->next) { |
setvareq(savestr(lp->text), 0); |
} |
INTON; |
} |
/* |
* Find the value of a variable. Returns NULL if not set. |
*/ |
char * |
lookupvar(name) |
const char *name; |
{ |
struct var *v; |
for (v = *hashvar(name) ; v ; v = v->next) { |
if (varequal(v->text, name)) { |
if (v->flags & VUNSET) |
return NULL; |
return strchr(v->text, '=') + 1; |
} |
} |
return NULL; |
} |
/* |
* Search the environment of a builtin command. If the second argument |
* is nonzero, return the value of a variable even if it hasn't been |
* exported. |
*/ |
char * |
bltinlookup(name, doall) |
const char *name; |
int doall; |
{ |
struct strlist *sp; |
struct var *v; |
for (sp = cmdenviron ; sp ; sp = sp->next) { |
if (varequal(sp->text, name)) |
return strchr(sp->text, '=') + 1; |
} |
for (v = *hashvar(name) ; v ; v = v->next) { |
if (varequal(v->text, name)) { |
if ((v->flags & VUNSET) |
|| (!doall && (v->flags & VEXPORT) == 0)) |
return NULL; |
return strchr(v->text, '=') + 1; |
} |
} |
return NULL; |
} |
/* |
* Generate a list of exported variables. This routine is used to construct |
* the third argument to execve when executing a program. |
*/ |
char ** |
environment() { |
int nenv; |
struct var **vpp; |
struct var *vp; |
char **env; |
char **ep; |
nenv = 0; |
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { |
for (vp = *vpp ; vp ; vp = vp->next) |
if (vp->flags & VEXPORT) |
nenv++; |
} |
ep = env = stalloc((nenv + 1) * sizeof *env); |
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { |
for (vp = *vpp ; vp ; vp = vp->next) |
if (vp->flags & VEXPORT) |
*ep++ = vp->text; |
} |
*ep = NULL; |
return env; |
} |
/* |
* Called when a shell procedure is invoked to clear out nonexported |
* variables. It is also necessary to reallocate variables of with |
* VSTACK set since these are currently allocated on the stack. |
*/ |
#ifdef mkinit |
MKINIT void shprocvar (void); |
SHELLPROC { |
shprocvar(); |
} |
#endif |
void |
shprocvar() { |
struct var **vpp; |
struct var *vp, **prev; |
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { |
for (prev = vpp ; (vp = *prev) != NULL ; ) { |
if ((vp->flags & VEXPORT) == 0) { |
*prev = vp->next; |
if ((vp->flags & VTEXTFIXED) == 0) |
ckfree(vp->text); |
if ((vp->flags & VSTRFIXED) == 0) |
ckfree(vp); |
} else { |
if (vp->flags & VSTACK) { |
vp->text = savestr(vp->text); |
vp->flags &=~ VSTACK; |
} |
prev = &vp->next; |
} |
} |
} |
initvar(); |
} |
/* |
* Command to list all variables which are set. Currently this command |
* is invoked from the set command when the set command is called without |
* any variables. |
*/ |
int |
showvarscmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct var **vpp; |
struct var *vp; |
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { |
for (vp = *vpp ; vp ; vp = vp->next) { |
if ((vp->flags & VUNSET) == 0) |
out1fmt("%s\n", vp->text); |
} |
} |
return 0; |
} |
/* |
* The export and readonly commands. |
*/ |
int |
exportcmd(argc, argv) |
int argc; |
char **argv; |
{ |
struct var **vpp; |
struct var *vp; |
char *name; |
const char *p; |
int flag = argv[0][0] == 'r'? VREADONLY : VEXPORT; |
int pflag; |
listsetvar(cmdenviron); |
pflag = (nextopt("p") == 'p'); |
if (argc > 1 && !pflag) { |
while ((name = *argptr++) != NULL) { |
if ((p = strchr(name, '=')) != NULL) { |
p++; |
} else { |
vpp = hashvar(name); |
for (vp = *vpp ; vp ; vp = vp->next) { |
if (varequal(vp->text, name)) { |
vp->flags |= flag; |
goto found; |
} |
} |
} |
setvar(name, p, flag); |
found:; |
} |
} else { |
for (vpp = vartab ; vpp < vartab + VTABSIZE ; vpp++) { |
for (vp = *vpp ; vp ; vp = vp->next) { |
if ((vp->flags & flag) == 0) |
continue; |
if (pflag) { |
out1fmt("%s %s\n", argv[0], vp->text); |
} else { |
for (p = vp->text ; *p != '=' ; p++) |
out1c(*p); |
out1c('\n'); |
} |
} |
} |
} |
return 0; |
} |
/* |
* The "local" command. |
*/ |
int |
localcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char *name; |
if (! in_function()) |
error("Not in a function"); |
while ((name = *argptr++) != NULL) { |
mklocal(name); |
} |
return 0; |
} |
/* |
* Make a variable a local variable. When a variable is made local, it's |
* value and flags are saved in a localvar structure. The saved values |
* will be restored when the shell function returns. We handle the name |
* "-" as a special case. |
*/ |
void |
mklocal(name) |
char *name; |
{ |
struct localvar *lvp; |
struct var **vpp; |
struct var *vp; |
INTOFF; |
lvp = ckmalloc(sizeof (struct localvar)); |
if (name[0] == '-' && name[1] == '\0') { |
char *p; |
p = ckmalloc(sizeof optlist); |
lvp->text = memcpy(p, optlist, sizeof optlist); |
vp = NULL; |
} else { |
vpp = hashvar(name); |
for (vp = *vpp ; vp && ! varequal(vp->text, name) ; vp = vp->next); |
if (vp == NULL) { |
if (strchr(name, '=')) |
setvareq(savestr(name), VSTRFIXED); |
else |
setvar(name, NULL, VSTRFIXED); |
vp = *vpp; /* the new variable */ |
lvp->text = NULL; |
lvp->flags = VUNSET; |
} else { |
lvp->text = vp->text; |
lvp->flags = vp->flags; |
vp->flags |= VSTRFIXED|VTEXTFIXED; |
if (strchr(name, '=')) |
setvareq(savestr(name), 0); |
} |
} |
lvp->vp = vp; |
lvp->next = localvars; |
localvars = lvp; |
INTON; |
} |
/* |
* Called after a function returns. |
*/ |
void |
poplocalvars() { |
struct localvar *lvp; |
struct var *vp; |
while ((lvp = localvars) != NULL) { |
localvars = lvp->next; |
vp = lvp->vp; |
if (vp == NULL) { /* $- saved */ |
memcpy(optlist, lvp->text, sizeof optlist); |
ckfree(lvp->text); |
} else if ((lvp->flags & (VUNSET|VSTRFIXED)) == VUNSET) { |
(void)unsetvar(vp->text); |
} else { |
if ((vp->flags & VTEXTFIXED) == 0) |
ckfree(vp->text); |
vp->flags = lvp->flags; |
vp->text = lvp->text; |
} |
ckfree(lvp); |
} |
} |
int |
setvarcmd(argc, argv) |
int argc; |
char **argv; |
{ |
if (argc <= 2) |
return unsetcmd(argc, argv); |
else if (argc == 3) |
setvar(argv[1], argv[2], 0); |
else |
error("List assignment not implemented"); |
return 0; |
} |
/* |
* The unset builtin command. We unset the function before we unset the |
* variable to allow a function to be unset when there is a readonly variable |
* with the same name. |
*/ |
int |
unsetcmd(argc, argv) |
int argc; |
char **argv; |
{ |
char **ap; |
int i; |
int flg_func = 0; |
int flg_var = 0; |
int ret = 0; |
while ((i = nextopt("vf")) != '\0') { |
if (i == 'f') |
flg_func = 1; |
else |
flg_var = 1; |
} |
if (flg_func == 0 && flg_var == 0) |
flg_var = 1; |
for (ap = argptr; *ap ; ap++) { |
if (flg_func) |
ret |= unsetfunc(*ap); |
if (flg_var) |
ret |= unsetvar(*ap); |
} |
return ret; |
} |
/* |
* Unset the specified variable. |
*/ |
int |
unsetvar(s) |
const char *s; |
{ |
struct var **vpp; |
struct var *vp; |
vpp = hashvar(s); |
for (vp = *vpp ; vp ; vpp = &vp->next, vp = *vpp) { |
if (varequal(vp->text, s)) { |
if (vp->flags & VREADONLY) |
return (1); |
INTOFF; |
if (*(strchr(vp->text, '=') + 1) != '\0') |
setvar(s, nullstr, 0); |
vp->flags &= ~VEXPORT; |
vp->flags |= VUNSET; |
if ((vp->flags & VSTRFIXED) == 0) { |
if ((vp->flags & VTEXTFIXED) == 0) |
ckfree(vp->text); |
*vpp = vp->next; |
ckfree(vp); |
} |
INTON; |
return (0); |
} |
} |
return (1); |
} |
/* |
* Find the appropriate entry in the hash table from the name. |
*/ |
STATIC struct var ** |
hashvar(p) |
const char *p; |
{ |
unsigned int hashval; |
hashval = ((unsigned char) *p) << 4; |
while (*p && *p != '=') |
hashval += (unsigned char) *p++; |
return &vartab[hashval % VTABSIZE]; |
} |
/* |
* Returns true if the two strings specify the same varable. The first |
* variable name is terminated by '='; the second may be terminated by |
* either '=' or '\0'. |
*/ |
STATIC int |
varequal(p, q) |
const char *p, *q; |
{ |
while (*p == *q++) { |
if (*p++ == '=') |
return 1; |
} |
if (*p == '=' && *(q - 1) == '\0') |
return 1; |
return 0; |
} |
/branches/dd/uspace/app/ash/miscbltin.h |
---|
0,0 → 1,34 |
/* $NetBSD: miscbltin.h,v 1.1 1997/07/04 21:02:10 christos Exp $ */ |
/* |
* Copyright (c) 1997 Christos Zoulas. All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by Christos Zoulas. |
* 4. The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
int readcmd (int, char **); |
int umaskcmd (int, char **); |
int ulimitcmd (int, char **); |
/branches/dd/uspace/app/ash/main.h |
---|
0,0 → 1,48 |
/* $NetBSD: main.h,v 1.8 1995/05/11 21:29:27 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)main.h 8.2 (Berkeley) 5/4/95 |
*/ |
extern int rootpid; /* pid of main shell */ |
extern int rootshell; /* true if we aren't a child of the main shell */ |
void readcmdfile (char *); |
void cmdloop (int); |
int dotcmd (int, char **); |
int exitcmd (int, char **); |
/branches/dd/uspace/app/ash/options.c |
---|
0,0 → 1,551 |
/* $NetBSD: options.c,v 1.29 1999/07/09 03:05:50 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)options.c 8.2 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: options.c,v 1.29 1999/07/09 03:05:50 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <signal.h> |
#include <unistd.h> |
#include <stdlib.h> |
#include "shell.h" |
#define DEFINE_OPTIONS |
#include "options.h" |
#undef DEFINE_OPTIONS |
#include "nodes.h" /* for other header files */ |
#include "eval.h" |
#include "jobs.h" |
#include "input.h" |
#include "output.h" |
#include "trap.h" |
#include "var.h" |
#include "memalloc.h" |
#include "error.h" |
#include "mystring.h" |
#ifndef SMALL |
#include "myhistedit.h" |
#endif |
char *arg0; /* value of $0 */ |
struct shparam shellparam; /* current positional parameters */ |
char **argptr; /* argument list for builtin commands */ |
char *optarg; /* set by nextopt (like getopt) */ |
char *optptr; /* used by nextopt */ |
char *minusc; /* argument to -c option */ |
STATIC void options (int); |
STATIC void minus_o (char *, int); |
STATIC void setoption (int, int); |
STATIC int getopts (char *, char *, char **, int *, int *); |
/* |
* Process the shell command line arguments. |
*/ |
void |
procargs(argc, argv) |
int argc; |
char **argv; |
{ |
int i; |
argptr = argv; |
if (argc > 0) |
argptr++; |
for (i = 0; i < NOPTS; i++) |
optlist[i].val = 2; |
options(1); |
if (*argptr == NULL && minusc == NULL) |
sflag = 1; |
if (iflag == 2 && sflag == 1 && isatty(0) && isatty(1)) |
iflag = 1; |
if (mflag == 2) |
mflag = iflag; |
for (i = 0; i < NOPTS; i++) |
if (optlist[i].val == 2) |
optlist[i].val = 0; |
arg0 = argv[0]; |
if (sflag == 0 && minusc == NULL) { |
commandname = arg0 = *argptr++; |
setinputfile(commandname, 0); |
} |
/* POSIX 1003.2: first arg after -c cmd is $0, remainder $1... */ |
if (argptr && minusc && *argptr) |
arg0 = *argptr++; |
shellparam.p = argptr; |
shellparam.optind = 1; |
shellparam.optoff = -1; |
/* assert(shellparam.malloc == 0 && shellparam.nparam == 0); */ |
while (*argptr) { |
shellparam.nparam++; |
argptr++; |
} |
optschanged(); |
} |
void |
optschanged() |
{ |
setinteractive(iflag); |
#ifndef SMALL |
histedit(); |
#endif |
setjobctl(mflag); |
} |
/* |
* Process shell options. The global variable argptr contains a pointer |
* to the argument list; we advance it past the options. |
*/ |
STATIC void |
options(cmdline) |
int cmdline; |
{ |
char *p; |
int val; |
int c; |
if (cmdline) |
minusc = NULL; |
while ((p = *argptr) != NULL) { |
argptr++; |
if ((c = *p++) == '-') { |
val = 1; |
if (p[0] == '\0' || (p[0] == '-' && p[1] == '\0')) { |
if (!cmdline) { |
/* "-" means turn off -x and -v */ |
if (p[0] == '\0') |
xflag = vflag = 0; |
/* "--" means reset params */ |
else if (*argptr == NULL) |
setparam(argptr); |
} |
break; /* "-" or "--" terminates options */ |
} |
} else if (c == '+') { |
val = 0; |
} else { |
argptr--; |
break; |
} |
while ((c = *p++) != '\0') { |
if (c == 'c' && cmdline) { |
char *q; |
#ifdef NOHACK /* removing this code allows sh -ce 'foo' for compat */ |
if (*p == '\0') |
#endif |
q = *argptr++; |
if (q == NULL || minusc != NULL) |
error("Bad -c option"); |
minusc = q; |
#ifdef NOHACK |
break; |
#endif |
} else if (c == 'o') { |
minus_o(*argptr, val); |
if (*argptr) |
argptr++; |
} else { |
setoption(c, val); |
} |
} |
} |
} |
STATIC void |
minus_o(name, val) |
char *name; |
int val; |
{ |
int i; |
if (name == NULL) { |
out1str("Current option settings\n"); |
for (i = 0; i < NOPTS; i++) |
out1fmt("%-16s%s\n", optlist[i].name, |
optlist[i].val ? "on" : "off"); |
} else { |
for (i = 0; i < NOPTS; i++) |
if (equal(name, optlist[i].name)) { |
setoption(optlist[i].letter, val); |
return; |
} |
error("Illegal option -o %s", name); |
} |
} |
STATIC void |
setoption(flag, val) |
char flag; |
int val; |
{ |
int i; |
for (i = 0; i < NOPTS; i++) |
if (optlist[i].letter == flag) { |
optlist[i].val = val; |
if (val) { |
/* #%$ hack for ksh semantics */ |
if (flag == 'V') |
Eflag = 0; |
else if (flag == 'E') |
Vflag = 0; |
} |
return; |
} |
error("Illegal option -%c", flag); |
/* NOTREACHED */ |
} |
#ifdef mkinit |
INCLUDE "options.h" |
SHELLPROC { |
int i; |
for (i = 0; i < NOPTS; i++) |
optlist[i].val = 0; |
optschanged(); |
} |
#endif |
/* |
* Set the shell parameters. |
*/ |
void |
setparam(argv) |
char **argv; |
{ |
char **newparam; |
char **ap; |
int nparam; |
for (nparam = 0 ; argv[nparam] ; nparam++); |
ap = newparam = ckmalloc((nparam + 1) * sizeof *ap); |
while (*argv) { |
*ap++ = savestr(*argv++); |
} |
*ap = NULL; |
freeparam(&shellparam); |
shellparam.malloc = 1; |
shellparam.nparam = nparam; |
shellparam.p = newparam; |
shellparam.optind = 1; |
shellparam.optoff = -1; |
} |
/* |
* Free the list of positional parameters. |
*/ |
void |
freeparam(param) |
volatile struct shparam *param; |
{ |
char **ap; |
if (param->malloc) { |
for (ap = param->p ; *ap ; ap++) |
ckfree(*ap); |
ckfree(param->p); |
} |
} |
/* |
* The shift builtin command. |
*/ |
int |
shiftcmd(argc, argv) |
int argc; |
char **argv; |
{ |
int n; |
char **ap1, **ap2; |
n = 1; |
if (argc > 1) |
n = number(argv[1]); |
if (n > shellparam.nparam) |
error("can't shift that many"); |
INTOFF; |
shellparam.nparam -= n; |
for (ap1 = shellparam.p ; --n >= 0 ; ap1++) { |
if (shellparam.malloc) |
ckfree(*ap1); |
} |
ap2 = shellparam.p; |
while ((*ap2++ = *ap1++) != NULL); |
shellparam.optind = 1; |
shellparam.optoff = -1; |
INTON; |
return 0; |
} |
/* |
* The set command builtin. |
*/ |
int |
setcmd(argc, argv) |
int argc; |
char **argv; |
{ |
if (argc == 1) |
return showvarscmd(argc, argv); |
INTOFF; |
options(0); |
optschanged(); |
if (*argptr != NULL) { |
setparam(argptr); |
} |
INTON; |
return 0; |
} |
void |
getoptsreset(value) |
const char *value; |
{ |
shellparam.optind = number(value); |
shellparam.optoff = -1; |
} |
/* |
* The getopts builtin. Shellparam.optnext points to the next argument |
* to be processed. Shellparam.optptr points to the next character to |
* be processed in the current argument. If shellparam.optnext is NULL, |
* then it's the first time getopts has been called. |
*/ |
int |
getoptscmd(argc, argv) |
int argc; |
char **argv; |
{ |
char **optbase; |
if (argc < 3) |
error("Usage: getopts optstring var [arg]"); |
else if (argc == 3) { |
optbase = shellparam.p; |
if (shellparam.optind > shellparam.nparam + 1) { |
shellparam.optind = 1; |
shellparam.optoff = -1; |
} |
} |
else { |
optbase = &argv[3]; |
if (shellparam.optind > argc - 2) { |
shellparam.optind = 1; |
shellparam.optoff = -1; |
} |
} |
return getopts(argv[1], argv[2], optbase, &shellparam.optind, |
&shellparam.optoff); |
} |
STATIC int |
getopts(optstr, optvar, optfirst, optind, optoff) |
char *optstr; |
char *optvar; |
char **optfirst; |
int *optind; |
int *optoff; |
{ |
char *p, *q; |
char c = '?'; |
int done = 0; |
int err = 0; |
char s[10]; |
char **optnext = optfirst + *optind - 1; |
if (*optind <= 1 || *optoff < 0 || !(*(optnext - 1)) || |
strlen(*(optnext - 1)) < *optoff) |
p = NULL; |
else |
p = *(optnext - 1) + *optoff; |
if (p == NULL || *p == '\0') { |
/* Current word is done, advance */ |
if (optnext == NULL) |
return 1; |
p = *optnext; |
if (p == NULL || *p != '-' || *++p == '\0') { |
atend: |
*optind = optnext - optfirst + 1; |
p = NULL; |
done = 1; |
goto out; |
} |
optnext++; |
if (p[0] == '-' && p[1] == '\0') /* check for "--" */ |
goto atend; |
} |
c = *p++; |
for (q = optstr; *q != c; ) { |
if (*q == '\0') { |
if (optstr[0] == ':') { |
s[0] = c; |
s[1] = '\0'; |
err |= setvarsafe("OPTARG", s, 0); |
} |
else { |
outfmt(&errout, "Illegal option -%c\n", c); |
(void) unsetvar("OPTARG"); |
} |
c = '?'; |
goto bad; |
} |
if (*++q == ':') |
q++; |
} |
if (*++q == ':') { |
if (*p == '\0' && (p = *optnext) == NULL) { |
if (optstr[0] == ':') { |
s[0] = c; |
s[1] = '\0'; |
err |= setvarsafe("OPTARG", s, 0); |
c = ':'; |
} |
else { |
outfmt(&errout, "No arg for -%c option\n", c); |
(void) unsetvar("OPTARG"); |
c = '?'; |
} |
goto bad; |
} |
if (p == *optnext) |
optnext++; |
setvarsafe("OPTARG", p, 0); |
p = NULL; |
} |
else |
setvarsafe("OPTARG", "", 0); |
*optind = optnext - optfirst + 1; |
goto out; |
bad: |
*optind = 1; |
p = NULL; |
out: |
*optoff = p ? p - *(optnext - 1) : -1; |
fmtstr(s, sizeof(s), "%d", *optind); |
err |= setvarsafe("OPTIND", s, VNOFUNC); |
s[0] = c; |
s[1] = '\0'; |
err |= setvarsafe(optvar, s, 0); |
if (err) { |
*optind = 1; |
*optoff = -1; |
flushall(); |
exraise(EXERROR); |
} |
return done; |
} |
/* |
* XXX - should get rid of. have all builtins use getopt(3). the |
* library getopt must have the BSD extension static variable "optreset" |
* otherwise it can't be used within the shell safely. |
* |
* Standard option processing (a la getopt) for builtin routines. The |
* only argument that is passed to nextopt is the option string; the |
* other arguments are unnecessary. It return the character, or '\0' on |
* end of input. |
*/ |
int |
nextopt(optstring) |
const char *optstring; |
{ |
char *p; |
const char *q; |
char c; |
if ((p = optptr) == NULL || *p == '\0') { |
p = *argptr; |
if (p == NULL || *p != '-' || *++p == '\0') |
return '\0'; |
argptr++; |
if (p[0] == '-' && p[1] == '\0') /* check for "--" */ |
return '\0'; |
} |
c = *p++; |
for (q = optstring ; *q != c ; ) { |
if (*q == '\0') |
error("Illegal option -%c", c); |
if (*++q == ':') |
q++; |
} |
if (*++q == ':') { |
if (*p == '\0' && (p = *argptr++) == NULL) |
error("No arg for -%c option", c); |
optarg = p; |
p = NULL; |
} |
optptr = p; |
return c; |
} |
/branches/dd/uspace/app/ash/eval.h |
---|
0,0 → 1,75 |
/* $NetBSD: eval.h,v 1.10 2000/01/27 23:39:40 christos Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)eval.h 8.2 (Berkeley) 5/4/95 |
*/ |
extern char *commandname; /* currently executing command */ |
extern int exitstatus; /* exit status of last command */ |
extern struct strlist *cmdenviron; /* environment for builtin command */ |
struct backcmd { /* result of evalbackcmd */ |
int fd; /* file descriptor to read from */ |
char *buf; /* buffer */ |
int nleft; /* number of chars in buffer */ |
struct job *jp; /* job structure for command */ |
}; |
int evalcmd (int, char **); |
void evalstring (char *, int); |
union node; /* BLETCH for ansi C */ |
void evaltree (union node *, int); |
void evalbackcmd (union node *, struct backcmd *); |
int bltincmd (int, char **); |
int breakcmd (int, char **); |
int returncmd (int, char **); |
int falsecmd (int, char **); |
int truecmd (int, char **); |
int execcmd (int, char **); |
int is_special_builtin (const char *); |
/* in_function returns nonzero if we are currently evaluating a function */ |
#define in_function() funcnest |
extern int funcnest; |
extern int evalskip; |
/* reasons for skipping commands (see comment on breakcmd routine) */ |
#define SKIPBREAK 1 |
#define SKIPCONT 2 |
#define SKIPFUNC 3 |
#define SKIPFILE 4 |
/branches/dd/uspace/app/ash/arith.y |
---|
0,0 → 1,202 |
%{ |
/* $NetBSD: arith.y,v 1.13 1999/07/09 03:05:49 christos Exp $ */ |
/*- |
* Copyright (c) 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
*/ |
#include <sys/cdefs.h> |
#ifndef lint |
#if 0 |
static char sccsid[] = "@(#)arith.y 8.3 (Berkeley) 5/4/95"; |
#else |
__RCSID("$NetBSD: arith.y,v 1.13 1999/07/09 03:05:49 christos Exp $"); |
#endif |
#endif /* not lint */ |
#include <stdlib.h> |
#include "expand.h" |
#include "shell.h" |
#include "error.h" |
#include "output.h" |
#include "memalloc.h" |
const char *arith_buf, *arith_startbuf; |
void yyerror (const char *); |
int yyparse (void); |
#ifdef TESTARITH |
int main (int , char *[]); |
int error (char *); |
#endif |
int |
arith(s) |
const char *s; |
{ |
long result; |
arith_buf = arith_startbuf = s; |
INTOFF; |
result = yyparse(); |
arith_lex_reset(); /* reprime lex */ |
INTON; |
return (result); |
} |
/* |
* The exp(1) builtin. |
*/ |
int |
expcmd(argc, argv) |
int argc; |
char **argv; |
{ |
const char *p; |
char *concat; |
char **ap; |
long i; |
if (argc > 1) { |
p = argv[1]; |
if (argc > 2) { |
/* |
* concatenate arguments |
*/ |
STARTSTACKSTR(concat); |
ap = argv + 2; |
for (;;) { |
while (*p) |
STPUTC(*p++, concat); |
if ((p = *ap++) == NULL) |
break; |
STPUTC(' ', concat); |
} |
STPUTC('\0', concat); |
p = grabstackstr(concat); |
} |
} else |
p = ""; |
i = arith(p); |
out1fmt("%ld\n", i); |
return (! i); |
} |
/*************************/ |
#ifdef TEST_ARITH |
#include <stdio.h> |
main(argc, argv) |
char *argv[]; |
{ |
printf("%d\n", exp(argv[1])); |
} |
error(s) |
char *s; |
{ |
fprintf(stderr, "exp: %s\n", s); |
exit(1); |
} |
#endif |
%} |
%token ARITH_NUM ARITH_LPAREN ARITH_RPAREN |
%left ARITH_OR |
%left ARITH_AND |
%left ARITH_BOR |
%left ARITH_BXOR |
%left ARITH_BAND |
%left ARITH_EQ ARITH_NE |
%left ARITH_LT ARITH_GT ARITH_GE ARITH_LE |
%left ARITH_LSHIFT ARITH_RSHIFT |
%left ARITH_ADD ARITH_SUB |
%left ARITH_MUL ARITH_DIV ARITH_REM |
%left ARITH_UNARYMINUS ARITH_UNARYPLUS ARITH_NOT ARITH_BNOT |
%% |
exp: expr { |
return ($1); |
} |
; |
expr: ARITH_LPAREN expr ARITH_RPAREN { $$ = $2; } |
| expr ARITH_OR expr { $$ = $1 ? $1 : $3 ? $3 : 0; } |
| expr ARITH_AND expr { $$ = $1 ? ( $3 ? $3 : 0 ) : 0; } |
| expr ARITH_BOR expr { $$ = $1 | $3; } |
| expr ARITH_BXOR expr { $$ = $1 ^ $3; } |
| expr ARITH_BAND expr { $$ = $1 & $3; } |
| expr ARITH_EQ expr { $$ = $1 == $3; } |
| expr ARITH_GT expr { $$ = $1 > $3; } |
| expr ARITH_GE expr { $$ = $1 >= $3; } |
| expr ARITH_LT expr { $$ = $1 < $3; } |
| expr ARITH_LE expr { $$ = $1 <= $3; } |
| expr ARITH_NE expr { $$ = $1 != $3; } |
| expr ARITH_LSHIFT expr { $$ = $1 << $3; } |
| expr ARITH_RSHIFT expr { $$ = $1 >> $3; } |
| expr ARITH_ADD expr { $$ = $1 + $3; } |
| expr ARITH_SUB expr { $$ = $1 - $3; } |
| expr ARITH_MUL expr { $$ = $1 * $3; } |
| expr ARITH_DIV expr { |
if ($3 == 0) |
yyerror("division by zero"); |
$$ = $1 / $3; |
} |
| expr ARITH_REM expr { |
if ($3 == 0) |
yyerror("division by zero"); |
$$ = $1 % $3; |
} |
| ARITH_NOT expr { $$ = !($2); } |
| ARITH_BNOT expr { $$ = ~($2); } |
| ARITH_SUB expr %prec ARITH_UNARYMINUS { $$ = -($2); } |
| ARITH_ADD expr %prec ARITH_UNARYPLUS { $$ = $2; } |
| ARITH_NUM |
; |
%% |
void |
yyerror(s) |
const char *s; |
{ |
yyclearin; |
arith_lex_reset(); /* reprime lex */ |
error("arithmetic expression: %s: \"%s\"", s, arith_startbuf); |
/* NOTREACHED */ |
} |
/branches/dd/uspace/app/ash/var.h |
---|
0,0 → 1,131 |
/* $NetBSD: var.h,v 1.18 2000/05/22 10:18:47 elric Exp $ */ |
/*- |
* Copyright (c) 1991, 1993 |
* The Regents of the University of California. All rights reserved. |
* |
* This code is derived from software contributed to Berkeley by |
* Kenneth Almquist. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* 1. Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* 2. Redistributions in binary form must reproduce the above copyright |
* notice, this list of conditions and the following disclaimer in the |
* documentation and/or other materials provided with the distribution. |
* 3. All advertising materials mentioning features or use of this software |
* must display the following acknowledgement: |
* This product includes software developed by the University of |
* California, Berkeley and its contributors. |
* 4. Neither the name of the University nor the names of its contributors |
* may be used to endorse or promote products derived from this software |
* without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
* SUCH DAMAGE. |
* |
* @(#)var.h 8.2 (Berkeley) 5/4/95 |
*/ |
/* |
* Shell variables. |
*/ |
/* flags */ |
#define VEXPORT 0x01 /* variable is exported */ |
#define VREADONLY 0x02 /* variable cannot be modified */ |
#define VSTRFIXED 0x04 /* variable struct is staticly allocated */ |
#define VTEXTFIXED 0x08 /* text is staticly allocated */ |
#define VSTACK 0x10 /* text is allocated on the stack */ |
#define VUNSET 0x20 /* the variable is not set */ |
#define VNOFUNC 0x40 /* don't call the callback function */ |
struct var { |
struct var *next; /* next entry in hash list */ |
int flags; /* flags are defined above */ |
char *text; /* name=value */ |
void (*func) (const char *); |
/* function to be called when */ |
/* the variable gets set/unset */ |
}; |
struct localvar { |
struct localvar *next; /* next local variable in list */ |
struct var *vp; /* the variable that was made local */ |
int flags; /* saved flags */ |
char *text; /* saved text */ |
}; |
struct localvar *localvars; |
#if ATTY |
extern struct var vatty; |
#endif |
extern struct var vifs; |
extern struct var vmail; |
extern struct var vmpath; |
extern struct var vpath; |
extern struct var vps1; |
extern struct var vps2; |
#ifndef SMALL |
extern struct var vterm; |
extern struct var vtermcap; |
extern struct var vhistsize; |
#endif |
/* |
* The following macros access the values of the above variables. |
* They have to skip over the name. They return the null string |
* for unset variables. |
*/ |
#define ifsval() (vifs.text + 4) |
#define ifsset() ((vifs.flags & VUNSET) == 0) |
#define mailval() (vmail.text + 5) |
#define mpathval() (vmpath.text + 9) |
#define pathval() (vpath.text + 5) |
#define ps1val() (vps1.text + 4) |
#define ps2val() (vps2.text + 4) |
#define optindval() (voptind.text + 7) |
#ifndef SMALL |
#define histsizeval() (vhistsize.text + 9) |
#define termval() (vterm.text + 5) |
#endif |
#if ATTY |
#define attyset() ((vatty.flags & VUNSET) == 0) |
#endif |
#define mpathset() ((vmpath.flags & VUNSET) == 0) |
void initvar (void); |
void setvar (const char *, const char *, int); |
void setvareq (char *, int); |
struct strlist; |
void listsetvar (struct strlist *); |
char *lookupvar (const char *); |
char *bltinlookup (const char *, int); |
char **environment (void); |
void shprocvar (void); |
int showvarscmd (int, char **); |
int exportcmd (int, char **); |
int localcmd (int, char **); |
void mklocal (char *); |
void poplocalvars (void); |
int setvarcmd (int, char **); |
int unsetcmd (int, char **); |
int unsetvar (const char *); |
int setvarsafe (const char *, const char *, int); |
/branches/dd/uspace/app/klog/klog.c |
---|
27,9 → 27,9 |
*/ |
/** @addtogroup klog KLog |
* @brief HelenOS KLog |
* @brief HelenOS KLog |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
40,56 → 40,46 |
#include <ipc/services.h> |
#include <as.h> |
#include <sysinfo.h> |
#include <io/stream.h> |
#include <errno.h> |
#define NAME "klog" |
#define KLOG_SIZE PAGE_SIZE |
/* Pointer to klog area */ |
static char *klog; |
static void interrupt_received(ipc_callid_t callid, ipc_call_t *call) |
{ |
int i; |
async_serialize_start(); |
size_t klog_start = (size_t) IPC_GET_ARG1(*call); |
size_t klog_len = (size_t) IPC_GET_ARG2(*call); |
size_t klog_stored = (size_t) IPC_GET_ARG3(*call); |
size_t i; |
for (i = klog_len - klog_stored; i < klog_len; i++) |
putchar(klog[(klog_start + i) % KLOG_SIZE]); |
for (i=0; klog[i + IPC_GET_ARG1(*call)] && i < IPC_GET_ARG2(*call); i++) |
putchar(klog[i + IPC_GET_ARG1(*call)]); |
putchar('\n'); |
async_serialize_end(); |
} |
int main(int argc, char *argv[]) |
{ |
console_wait(); |
int res; |
void *mapping; |
printf("Kernel console output.\n"); |
klog = (char *) as_get_mappable_page(KLOG_SIZE); |
if (klog == NULL) { |
printf(NAME ": Error allocating memory area\n"); |
return -1; |
} |
int res = ipc_share_in_start_1_0(PHONE_NS, (void *) klog, KLOG_SIZE, |
mapping = as_get_mappable_page(PAGE_SIZE); |
res = ipc_share_in_start_1_0(PHONE_NS, mapping, PAGE_SIZE, |
SERVICE_MEM_KLOG); |
if (res != EOK) { |
printf(NAME ": Error initializing memory area\n"); |
return -1; |
if (res) { |
printf("Failed to initialize klog memarea\n"); |
_exit(1); |
} |
klog = mapping; |
int inr = sysinfo_value("klog.inr"); |
int devno = sysinfo_value("klog.devno"); |
int inr = sysinfo_value("klog.inr"); |
if (ipc_register_irq(inr, devno, 0, NULL) != EOK) { |
printf(NAME ": Error registering klog notifications\n"); |
return -1; |
if (ipc_register_irq(inr, devno, 0, NULL)) { |
printf("Error registering for klog service.\n"); |
return 0; |
} |
async_set_interrupt_received(interrupt_received); |
klog_update(); |
async_manager(); |
return 0; |
/branches/dd/uspace/app/klog/Makefile |
---|
31,7 → 31,6 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
48,24 → 47,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/tetris/screen.c |
---|
50,12 → 50,13 |
#include <stdlib.h> |
#include <string.h> |
#include <unistd.h> |
#include <console.h> |
#include <io/stream.h> |
#include <async.h> |
#include "screen.h" |
#include "tetris.h" |
#include <ipc/console.h> |
#include "../../srv/console/console.h" |
static cell curscreen[B_SIZE]; /* 1 => standout (or otherwise marked) */ |
static int curscore; |
72,19 → 73,29 |
putchar(*(s++)); |
} |
static int con_phone; |
static void set_style(int fgcolor, int bgcolor) |
{ |
async_msg_2(con_phone, CONSOLE_SET_STYLE, fgcolor, bgcolor); |
} |
static void start_standout(void) |
{ |
console_set_rgb_color(0xf0f0f0, 0); |
set_style(0xf0f0f0, 0); |
} |
static void resume_normal(void) |
{ |
console_set_rgb_color(0, 0xf0f0f0); |
set_style(0, 0xf0f0f0); |
} |
void clear_screen(void) |
{ |
console_clear(); |
async_msg_0(con_phone, CONSOLE_CLEAR); |
moveto(0, 0); |
} |
96,7 → 107,7 |
{ |
resume_normal(); |
console_clear(); |
async_msg_0(con_phone, CONSOLE_CLEAR); |
curscore = -1; |
memset((char *)curscreen, 0, sizeof(curscreen)); |
} |
107,7 → 118,8 |
void |
scr_init(void) |
{ |
console_cursor_visibility(0); |
con_phone = get_cons_phone(); |
async_msg_1(con_phone, CONSOLE_CURSOR_VISIBILITY, 0); |
resume_normal(); |
scr_clear(); |
} |
114,12 → 126,12 |
void moveto(int r, int c) |
{ |
console_goto(r, c); |
async_msg_2(con_phone, CONSOLE_GOTO, r, c); |
} |
static void fflush(void) |
{ |
console_flush(); |
async_msg_0(con_phone, CONSOLE_FLUSH); |
} |
winsize_t winsize; |
126,7 → 138,8 |
static int get_display_size(winsize_t *ws) |
{ |
return console_get_size(&ws->ws_row, &ws->ws_col); |
return async_req_0_2(con_phone, CONSOLE_GETSIZE, &ws->ws_row, |
&ws->ws_col); |
} |
/* |
/branches/dd/uspace/app/tetris/input.c |
---|
57,8 → 57,7 |
#include "tetris.h" |
#include <async.h> |
#include <ipc/console.h> |
#include <kbd/kbd.h> |
#include "../../srv/console/console.h" |
/* return true iff the given timeval is positive */ |
#define TV_POS(tv) \ |
97,7 → 96,6 |
struct timeval starttv, endtv, *s; |
static ipc_call_t charcall; |
ipcarg_t rc; |
int cons_phone; |
/* |
* Someday, select() will do this for us. |
112,12 → 110,8 |
s = NULL; |
if (!lastchar) { |
again: |
if (!getchar_inprog) { |
cons_phone = get_console_phone(); |
getchar_inprog = async_send_2(cons_phone, |
CONSOLE_GETKEY, 0, 0, &charcall); |
} |
if (!getchar_inprog) |
getchar_inprog = async_send_2(1,CONSOLE_GETCHAR,0,0,&charcall); |
if (!s) |
async_wait_for(getchar_inprog, &rc); |
else if (async_wait_timeout(getchar_inprog, &rc, s->tv_usec) == ETIMEOUT) { |
129,10 → 123,7 |
if (rc) { |
stop("end of file, help"); |
} |
if (IPC_GET_ARG1(charcall) == KE_RELEASE) |
goto again; |
lastchar = IPC_GET_ARG4(charcall); |
lastchar = IPC_GET_ARG1(charcall); |
} |
if (tvp) { |
/* since there is input, we may not have timed out */ |
/branches/dd/uspace/app/tetris/Makefile |
---|
1,6 → 1,5 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
LIBS = $(LIBC_PREFIX)/libc.a |
11,7 → 10,7 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
19,16 → 18,13 |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend *.o |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
disasm: $(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/tetris/scores.c |
---|
52,7 → 52,7 |
/* #include <err.h> */ |
/* #include <fcntl.h> */ |
/* #include <pwd.h> */ |
#include <stdio.h> |
#include <stdio.h> |
/* #include <stdlib.h> */ |
#include <string.h> |
/* #include <time.h> */ |
/branches/dd/uspace/app/tetris/screen.h |
---|
49,8 → 49,8 |
#include <async.h> |
typedef struct { |
int ws_row; |
int ws_col; |
ipcarg_t ws_row; |
ipcarg_t ws_col; |
} winsize_t; |
extern winsize_t winsize; |
/branches/dd/uspace/app/init/Makefile |
---|
27,6 → 27,7 |
# |
include ../../../version |
include ../../Makefile.config |
## Setup toolchain |
# |
33,14 → 34,21 |
LIBC_PREFIX = ../../lib/libc |
SOFTINT_PREFIX = ../../lib/softint |
include $(LIBC_PREFIX)/Makefile.toolchain |
CFLAGS += -I../../srv/kbd/include |
LIBS = $(LIBC_PREFIX)/libc.a |
DEFS += -DRELEASE=$(RELEASE) |
DEFS += -DRELEASE=\"$(RELEASE)\" |
ifdef REVISION |
DEFS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
DEFS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
## Sources |
# |
53,24 → 61,22 |
.PHONY: all clean depend disasm |
all: $(OUTPUT) $(OUTPUT).disasm |
all: $(OUTPUT) disasm |
-include Makefile.depend |
clean: |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend $(OBJECTS) |
-rm -f $(OUTPUT) $(OUTPUT).map $(OUTPUT).disasm Makefile.depend |
depend: |
$(CC) $(DEFS) $(CFLAGS) -M $(SOURCES) > Makefile.depend |
$(OUTPUT): $(OBJECTS) $(LIBS) |
$(LD) -T $(LIBC_PREFIX)/arch/$(UARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
$(LD) -T $(LIBC_PREFIX)/arch/$(ARCH)/_link.ld $(OBJECTS) $(LIBS) $(LFLAGS) -o $@ -Map $(OUTPUT).map |
disasm: $(OUTPUT).disasm |
disasm: |
$(OBJDUMP) -d $(OUTPUT) >$(OUTPUT).disasm |
$(OUTPUT).disasm: $(OUTPUT) |
$(OBJDUMP) -d $< >$@ |
%.o: %.S |
$(CC) $(DEFS) $(AFLAGS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/uspace/app/init/init.c |
---|
27,93 → 27,37 |
*/ |
/** @addtogroup init Init |
* @brief Init process for user space environment configuration. |
* @brief Init process for testing purposes. |
* @{ |
*/ |
*/ |
/** |
* @file |
*/ |
#include "version.h" |
#include <stdio.h> |
#include <unistd.h> |
#include <ipc/ipc.h> |
#include <vfs/vfs.h> |
#include <bool.h> |
#include <errno.h> |
#include <fcntl.h> |
#include <task.h> |
#include <malloc.h> |
#include <macros.h> |
#include "init.h" |
#include "version.h" |
static bool mount_fs(const char *fstype) |
static void test_console(void) |
{ |
int rc = -1; |
while (rc < 0) { |
rc = mount(fstype, "/", "initrd", IPC_FLAG_BLOCKING); |
switch (rc) { |
case EOK: |
printf(NAME ": Root filesystem mounted\n"); |
break; |
case EBUSY: |
printf(NAME ": Root filesystem already mounted\n"); |
break; |
case ELIMIT: |
printf(NAME ": Unable to mount root filesystem\n"); |
return false; |
case ENOENT: |
printf(NAME ": Unknown filesystem type (%s)\n", fstype); |
return false; |
} |
} |
return true; |
} |
int c; |
static void spawn(char *fname) |
{ |
char *argv[2]; |
printf(NAME ": Spawning %s\n", fname); |
argv[0] = fname; |
argv[1] = NULL; |
if (task_spawn(fname, argv)) |
/* Add reasonable delay to avoid |
intermixed klog output */ |
usleep(10000); |
else |
printf(NAME ": Error spawning %s\n", fname); |
while ((c = getchar()) != EOF) |
putchar(c); |
} |
int main(int argc, char *argv[]) |
{ |
info_print(); |
if (!mount_fs(STRING(RDFMT))) { |
printf(NAME ": Exiting\n"); |
return -1; |
} |
// FIXME: spawn("/srv/pci"); |
spawn("/srv/fb"); |
spawn("/srv/kbd"); |
spawn("/srv/console"); |
spawn("/srv/fhc"); |
spawn("/srv/obio"); |
console_wait(); |
version_print(); |
printf("This is init\n"); |
spawn("/app/klog"); |
spawn("/app/bdsh"); |
test_console(); |
printf("\nBye.\n"); |
return 0; |
} |
/** @} |
*/ |
/branches/dd/uspace/app/init/version.c |
---|
35,29 → 35,22 |
#include <unistd.h> |
#include <stdio.h> |
#include <macros.h> |
#include "init.h" |
#include "version.h" |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
void info_print(void) |
{ |
printf(NAME ": HelenOS init\n"); |
} |
/** Print version information. */ |
void version_print(void) |
{ |
/branches/dd/uspace/app/init/init.h |
---|
36,7 → 36,7 |
#ifndef __INIT_H__ |
#define __INIT_H__ |
#define NAME "init" |
#include "version.h" |
#endif |
/branches/dd/uspace/app/init/version.h |
---|
36,7 → 36,6 |
#ifndef __VERSION_H__ |
#define __VERSION_H__ |
extern void info_print(void); |
extern void version_print(void); |
#endif |
/branches/dd/uspace/uspace.config |
---|
0,0 → 1,68 |
# |
# Copyright (c) 2006 Ondrej Palkovsky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## General configuration directives |
# Architecture |
@ "amd64" AMD64/Intel EM64T |
@ "arm32" ARM 32-bit |
@ "ia32" Intel IA-32 |
@ "ia64" Intel IA-64 |
@ "mips32" MIPS 32-bit Little Endian |
@ "mips32eb" MIPS 32-bit Big Endian |
@ "ppc32" PowerPC 32-bit |
@ "ppc64" PowerPC 64-bit |
@ "sparc64" Sun UltraSPARC 64-bit |
! ARCH (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=amd64|ARCH=ia32] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
! [ARCH=ia64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=sparc64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
! [ARCH=arm32|ARCH=mips32|ARCH=mips32eb|ARCH=ppc32|ARCH=ppc64] COMPILER (choice) |
# General debuging and assert checking |
! CONFIG_DEBUG (y/n) |
/branches/dd/uspace/Makefile |
---|
29,16 → 29,14 |
## Include configuration |
# |
-include ../Makefile.config |
-include Makefile.config |
DIRS = \ |
lib/libc \ |
lib/libfs \ |
lib/libblock \ |
lib/softint \ |
lib/softfloat \ |
srv/ns \ |
srv/loader \ |
srv/fb \ |
srv/kbd \ |
srv/console \ |
49,36 → 47,48 |
srv/devmap \ |
app/tetris \ |
app/tester \ |
app/trace \ |
app/klog \ |
app/init \ |
app/bdsh |
app/init |
ifeq ($(UARCH),amd64) |
ifeq ($(ARCH), amd64) |
DIRS += srv/pci |
endif |
ifeq ($(UARCH),ia32) |
ifeq ($(ARCH), ia32) |
DIRS += srv/pci |
endif |
ifeq ($(UARCH),sparc64) |
DIRS += \ |
srv/fhc \ |
srv/obio |
ifeq ($(ARCH), mips32) |
CFLAGS += -DCONFIG_MIPS_FPU |
endif |
ifeq ($(ARCH), mips32eb) |
CFLAGS += -DCONFIG_MIPS_FPU |
endif |
BUILDS := $(addsuffix .build,$(DIRS)) |
CLEANS := $(addsuffix .clean,$(DIRS)) |
.PHONY: all $(BUILDS) $(CLEANS) clean |
.PHONY: all config build $(BUILDS) $(CLEANS) clean distclean |
all: ../Makefile.config ../config.h ../config.defs $(BUILDS) |
all: |
../tools/config.py uspace.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) |
$(MAKE) -C . build |
config: |
../tools/config.py uspace.config |
build: $(BUILDS) |
clean: $(CLEANS) |
find $(DIRS) -name '*.o' -follow -exec rm \{\} \; |
find lib/libc -name "_link.ld" -exec rm \{\} \; |
distclean: clean |
-rm Makefile.config |
$(CLEANS): |
-$(MAKE) -C $(basename $@) clean |
-$(MAKE) -C $(basename $@) clean ARCH=$(ARCH) |
$(BUILDS): |
$(MAKE) -C $(basename $@) all |
$(MAKE) -C $(basename $@) all ARCH=$(ARCH) COMPILER=$(COMPILER) |
/branches/dd/HelenOS.config |
---|
1,6 → 1,5 |
# |
# Copyright (c) 2006 Ondrej Palkovsky |
# Copyright (c) 2009 Martin Decky |
# Copyright (c) 2006 Ondrej Palkovsky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
27,408 → 26,60 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## General platform options |
## General configuration directives |
% Platform |
# Platform |
@ "amd64" AMD64/Intel EM64T (PC) |
@ "arm32" ARM 32-bit |
@ "ia32" Intel IA-32 (PC) |
@ "ia32xen" Intel IA-32 on Xen hypervisor |
@ "ia64" Intel IA-64 |
@ "mips32" MIPS 32-bit |
@ "ppc32" PowerPC 32-bit (iMac G4) |
@ "ppc64" PowerPC 64-bit (iMac G5) |
@ "sparc64" Sun UltraSPARC 64-bit |
! PLATFORM (choice) |
% Machine type |
# Machine |
@ "msim" MSIM |
@ "simics" Simics |
@ "bgxemul" GXEmul big endian |
@ "lgxemul" GXEmul little endian |
@ "lgxemul" GXEmul little endia |
@ "indy" Sgi Indy |
! [PLATFORM=mips32] MACHINE (choice) |
% Machine type |
@ "gxemul" GXEmul |
! [PLATFORM=arm32] MACHINE (choice) |
% Machine type |
# Machine type |
@ "ski" Ski ia64 simulator |
@ "i460GX" i460GX chipset machine |
@ "ski" Ski ia64 simulator |
! [PLATFORM=ia64] MACHINE (choice) |
% Machine type |
@ "generic" Generic Sun workstation or server |
@ "serengeti" Serengeti system |
! [PLATFORM=sparc64] MACHINE (choice) |
# Machine |
@ "gxemul_testarm" GXEmul testarm |
! [PLATFORM=arm32] MACHINE (choice) |
% CPU type |
@ "pentium4" Pentium 4 |
@ "pentium3" Pentium 3 |
@ "core" Core Solo/Duo |
@ "athlon_xp" Athlon XP |
@ "athlon_mp" Athlon MP |
! [PLATFORM=ia32] PROCESSOR (choice) |
% CPU type |
@ "opteron" Opteron |
! [PLATFORM=amd64] PROCESSOR (choice) |
% CPU type |
@ "us" UltraSPARC I-II subarchitecture |
@ "us3" UltraSPARC III-IV subarchitecture |
! [PLATFORM=sparc64&MACHINE=generic] PROCESSOR (choice) |
% CPU type |
@ "us3" |
! [PLATFORM=sparc64&MACHINE=serengeti] PROCESSOR (choice) |
% Ramdisk format |
@ "tmpfs" TMPFS image |
@ "fat" FAT16 image |
! RDFMT (choice) |
## Mapping between platform and kernel architecture |
% Kernel architecture |
@ "amd64" |
! [PLATFORM=amd64] KARCH (choice) |
% Kernel architecture |
@ "arm32" |
! [PLATFORM=arm32] KARCH (choice) |
% Kernel architecture |
@ "ia32" |
! [PLATFORM=ia32] KARCH (choice) |
% Kernel architecture |
@ "ia32xen" |
! [PLATFORM=ia32xen] KARCH (choice) |
% Kernel architecture |
@ "ia64" |
! [PLATFORM=ia64] KARCH (choice) |
% Kernel architecture |
@ "mips32" |
! [PLATFORM=mips32] KARCH (choice) |
% Kernel architecture |
@ "ppc32" |
! [PLATFORM=ppc32] KARCH (choice) |
% Kernel architecture |
@ "ppc64" |
! [PLATFORM=ppc64] KARCH (choice) |
% Kernel architecture |
@ "sparc64" |
! [PLATFORM=sparc64] KARCH (choice) |
## Mapping between platform and user space architecture |
% User space architecture |
@ "amd64" |
! [PLATFORM=amd64] UARCH (choice) |
% User space architecture |
@ "arm32" |
! [PLATFORM=arm32] UARCH (choice) |
% User space architecture |
@ "ia32" |
! [PLATFORM=ia32|PLATFORM=ia32xen] UARCH (choice) |
% User space architecture |
@ "ia64" |
! [PLATFORM=ia64] UARCH (choice) |
% User space architecture |
@ "mips32" |
! [PLATFORM=mips32&(MACHINE=msim|MACHINE=simics|MACHINE=lgxemul)] UARCH (choice) |
% User space architecture |
@ "mips32eb" |
! [PLATFORM=mips32&MACHINE=bgxemul] UARCH (choice) |
% User space architecture |
@ "ppc32" |
! [PLATFORM=ppc32] UARCH (choice) |
% User space architecture |
@ "ppc64" |
! [PLATFORM=ppc64] UARCH (choice) |
% User space architecture |
@ "sparc64" |
! [PLATFORM=sparc64] UARCH (choice) |
## Mapping between platform and boot architecture |
% Boot architecture |
@ "amd64" |
! [PLATFORM=amd64] BARCH (choice) |
% Boot architecture |
@ "arm32" |
! [PLATFORM=arm32] BARCH (choice) |
% Boot architecture |
@ "ia32" |
! [PLATFORM=ia32] BARCH (choice) |
% Boot architecture |
@ "ia32xen" |
! [PLATFORM=ia32xen] BARCH (choice) |
% Boot architecture |
@ "ia64" |
! [PLATFORM=ia64] BARCH (choice) |
% Boot architecture |
@ "mips32" |
! [PLATFORM=mips32] BARCH (choice) |
% Boot architecture |
@ "ppc32" |
! [PLATFORM=ppc32] BARCH (choice) |
% Boot architecture |
@ "ppc64" |
! [PLATFORM=ppc64] BARCH (choice) |
% Boot architecture |
@ "sparc64" |
! [PLATFORM=sparc64] BARCH (choice) |
## Mapping between platform and image format |
% Image format |
@ "binary" |
! [PLATFORM=mips32&MACHINE=msim] IMAGE (choice) |
% Image format |
@ "ecoff" |
! [PLATFORM=mips32&(MACHINE=simics|MACHINE=bgxemul|MACHINE=lgxemul)] IMAGE (choice) |
## Compiler options |
% Compiler |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
@ "suncc_native" Sun Studio C Compiler |
! [PLATFORM=amd64|PLATFORM=ia32] COMPILER (choice) |
! [PLATFORM=amd64|PLATFORM=ia32|PLATFORM=ia32xen] COMPILER (choice) |
% Compiler |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
! [PLATFORM=ia64] COMPILER (choice) |
% Compiler |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "suncc_native" Sun Studio C Compiler |
! [PLATFORM=sparc64] COMPILER (choice) |
% Compiler |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] COMPILER (choice) |
! [PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=ppc64] COMPILER (choice) |
## Debug build options |
% Debug build |
# Debug build |
! CONFIG_DEBUG (y/n) |
% Deadlock detection support for spinlocks |
! [CONFIG_DEBUG=y&CONFIG_SMP=y] CONFIG_DEBUG_SPINLOCK (y/n) |
## Kernel configuration |
% Fences |
! [PLATFORM=ia32&(PROCESSOR=athlon_xp|PROCESSOR=athlon_mp|PROCESSOR=pentium3)] CONFIG_FENCES_P3 (y) |
% Fences |
! [PLATFORM=ia32&(PROCESSOR=pentium4|PROCESSOR=core)] CONFIG_FENCES_P4 (y) |
% Fences |
! [PLATFORM=amd64] CONFIG_FENCES_P4 (y) |
% ACPI support |
! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_ACPI (y) |
% Hierarchical page tables support |
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=arm32|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_PAGE_PT (y) |
% Page hash table support |
! [PLATFORM=ia64|PLATFORM=sparc64] CONFIG_PAGE_HT (y) |
% Software integer division support |
! [PLATFORM=ia32|PLATFORM=arm32|PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32] CONFIG_SOFTINT (y) |
% ASID support |
! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID (y) |
% ASID FIFO support |
! [PLATFORM=ia64|PLATFORM=mips32|PLATFORM=ppc32|PLATFORM=sparc64] CONFIG_ASID_FIFO (y) |
% OpenFirmware tree support |
! [PLATFORM=sparc64] CONFIG_OFW_TREE (y) |
% Multiboot standard support |
! [PLATFORM=ia32|PLATFORM=amd64] CONFIG_MULTIBOOT (y) |
% FPU support |
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=ia64|PLATFORM=sparc64] CONFIG_FPU (y) |
% FPU support |
! [PLATFORM=mips32&(MACHINE=lgxemul|MACHINE=bgxemul)] CONFIG_FPU (y) |
## Kernel features options |
% Support for SMP |
! [PLATFORM=ia32|PLATFORM=amd64|PLATFORM=sparc64|PLATFORM=ia64|(PLATFORM=mips32&MACHINE=msim)] CONFIG_SMP (y/n) |
% Improved support for hyperthreading |
! [PLATFORM=amd64&CONFIG_SMP=y] CONFIG_HT (y/n) |
% Improved support for hyperthreading |
! [PLATFORM=ia32&PROCESSOR!=athlon_xp&PROCESSOR!=athlon_mp&PROCESSOR!=pentium3&CONFIG_SMP=y] CONFIG_HT (y/n) |
% Lazy FPU context switching |
! [CONFIG_FPU=y] CONFIG_FPU_LAZY (y/n) |
% Use VHPT |
! [PLATFORM=ia64] CONFIG_VHPT (n/y) |
% Use TSB |
! [PLATFORM=sparc64] CONFIG_TSB (y/n) |
% IO SAPIC on default address support |
! [PLATFORM=ia64&MACHINE!=ski] CONFIG_IOSAPIC (y/n) |
% Virtually indexed D-cache support |
! [PLATFORM=sparc64] CONFIG_VIRT_IDX_DCACHE (y/n) |
% Support for userspace debuggers |
! CONFIG_UDEBUG (y/n) |
% Kernel console support |
! CONFIG_KCONSOLE (y/n) |
% Detailed kernel logging |
! CONFIG_LOG (n/y) |
% Compile kernel tests |
! CONFIG_TEST (y/n) |
## Hardware support |
% What is your input device? |
@ "generic" Keyboard or serial line |
@ "keyboard" Keyboard |
@ "serial" Serial line |
@ "none" No input device |
! [MACHINE!=msim&MACHINE!=ski&MACHINE!=serengeti] CONFIG_HID_IN (choice) |
% What is your input device? |
@ "serial" Serial line |
! [MACHINE=msim|MACHINE=ski|machine=serengeti] CONFIG_HID_IN (choice) |
% What is your output device? |
@ "generic" Monitor or serial line |
@ "monitor" Monitor |
@ "serial" Serial line |
@ "none" No output device |
! [MACHINE!=msim&MACHINE!=ski&MACHINE!=serengeti] CONFIG_HID_OUT (choice) |
% What is your output device? |
@ "serial" Serial line |
! [MACHINE=msim|MACHINE=ski&MACHINE=serengeti] CONFIG_HID_OUT (choice) |
% i8042 controller support |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_I8042 (y/n) |
% i8042 controller support |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&MACHINE=i460GX] CONFIG_I8042 (y/n) |
% Support for NS16550 controller |
! [CONFIG_HID_IN=generic|CONFIG_HID_IN=serial|(PLATFORM=sparc64&CONFIG_HID_OUT!=none&CONFIG_HID_IN!=none)] CONFIG_NS16550 (y/n) |
% Support for NS16550 serial port |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=serial|CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&MACHINE=i460GX] CONFIG_NS16550 (y/n) |
% Support for Z8530 controller |
! [(CONFIG_HID_IN!=none|CONFIG_HID_OUT=generic|CONFIG_HID_OUT=serial)&PLATFORM=sparc64] CONFIG_Z8530 (y/n) |
% Support for Serengeti console |
! [(CONFIG_HID_IN=serial|CONFIG_HID_OUT=serial)&MACHINE=serengeti] CONFIG_SGCN (y/n) |
% PC keyboard support |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_PC_KBD (y/n) |
% PC keyboard support |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&MACHINE=i460GX] CONFIG_PC_KBD (y/n) |
% Sun keyboard support |
! [(CONFIG_HID_IN=generic|CONFIG_HID_IN=keyboard)&PLATFORM=sparc64] CONFIG_SUN_KBD (y/n) |
% Serial line input module |
! [CONFIG_HID_IN=generic|CONFIG_HID_IN=serial] CONFIG_SRLN (y/n) |
% EGA support |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&(PLATFORM=ia32|PLATFORM=amd64)] CONFIG_EGA (y/n) |
% EGA support |
! [(CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor)&MACHINE=i460GX] CONFIG_EGA (y/n) |
% Framebuffer support |
! [CONFIG_HID_OUT=generic|CONFIG_HID_OUT=monitor] CONFIG_FB (y/n) |
% Framebuffer width |
@ "640" |
@ "800" |
@ "1024" |
@ "1152" |
@ "1280" |
@ "1400" |
@ "1440" |
@ "1600" |
@ "2048" |
! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_WIDTH (choice) |
% Framebuffer height |
@ "480" |
@ "600" |
@ "768" |
@ "852" |
@ "900" |
@ "960" |
@ "1024" |
@ "1050" |
@ "1200" |
@ "1536" |
! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_HEIGHT (choice) |
% Framebuffer depth |
@ "8" |
@ "16" |
@ "24" |
! [(PLATFORM=ia32|PLATFORM=amd64)&CONFIG_FB=y] CONFIG_VESA_BPP (choice) |
% Start AP processors by the loader |
! [PLATFORM=sparc64&CONFIG_SMP=y] CONFIG_AP (y/n) |
% Use Block Address Translation by the loader |
! [PLATFORM=ppc32] CONFIG_BAT (y/n) |
% Preserve A.OUT header in isofs.b |
! [PLATFORM=sparc64&MACHINE=generic] CONFIG_AOUT_ISOFS_B (y) |
% External ramdisk |
! [PLATFORM=sparc64] CONFIG_RD_EXTERNAL (y/n) |
% Keyboard layout |
@ "us_qwerty" US QWERTY |
@ "us_dvorak" US Dvorak |
! KBD_LAYOUT (choice) |
/branches/dd/boot/boot.config |
---|
0,0 → 1,80 |
# |
# Copyright (c) 2006 Ondrej Palkovsky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## General configuration directives |
# Architecture |
@ "amd64" AMD64/Intel EM64T |
@ "arm32" ARM 32-bit |
@ "ia32" Intel IA-32 |
@ "ia32xen" Intel IA-32 on Xen hypervisor |
@ "ia64" Intel IA-64 |
@ "mips32" MIPS 32-bit |
@ "ppc32" PowerPC 32-bit |
@ "ppc64" PowerPC 64-bit |
@ "sparc64" Sun UltraSPARC |
! ARCH (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=amd64|ARCH=ia32|ARCH=ia32xen] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "icc_native" ICC Native |
! [ARCH=ia64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
@ "suncc_native" Sun Studio C Compiler |
! [ARCH=sparc64] COMPILER (choice) |
# Compiler |
@ "gcc_cross" GCC Cross-compiler |
@ "gcc_native" GCC Native |
! [ARCH=arm32|ARCH=mips32|ARCH=ppc32|ARCH=ppc64] COMPILER (choice) |
# Start AP processors by the loader |
! [ARCH=sparc64] CONFIG_SMP (y/n) |
# Debug bootloader |
! [ARCH=ppc32] CONFIG_DEBUG (n/y) |
# Use Block Address Translation |
! [ARCH=ppc32] CONFIG_BAT (y/n) |
# Target image |
@ "binary" Binary image (MSIM) |
@ "ecoff" Ecoff image (GXEmul) |
! [ARCH=mips32] IMAGE (choice) |
/branches/dd/boot/arch/ia64/loader/_link.ld.in |
---|
File deleted |
/branches/dd/boot/arch/ia64/loader/gefi/Make.defaults |
---|
27,19 → 27,30 |
# |
INSTALLROOT=/usr/local |
TOPDIR := $(shell pwd) |
TOPDIR := $(shell if [ "$$PWD" != "" ]; then echo $$PWD; else pwd; fi) |
ARCH = ia64 |
INCDIR = -I. -I$(CDIR)/inc -I$(CDIR)/inc/$(ARCH) -I$(CDIR)/inc/protocol |
ARCH = $(shell uname -m | sed s,i[3456789]86,ia32,) |
INCDIR = -I. -I$(CDIR)/inc -I$(CDIR)/inc/$(ARCH) -I$(CDIR)/inc/protocol |
CPPFLAGS = -DCONFIG_$(ARCH) |
CFLAGS = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants -frename-registers -mfixed-range=f32-f127 |
LDFLAGS = -nostdlib |
INSTALL = install |
CFLAGS = -O2 -fpic -Wall -fshort-wchar -fno-strict-aliasing -fno-merge-constants |
LDFLAGS = -nostdlib |
INSTALL = install |
CC = $(prefix)gcc |
AS = $(prefix)as |
LD = $(prefix)ld |
AR = $(prefix)ar |
RANLIB = $(prefix)ranlib |
OBJCOPY = $(prefix)objcopy |
OBJDUMP = $(prefix)objdump |
GCC_VERSION=$(shell $(CROSS_COMPILE)$(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.') |
# prefix = |
CC = $(prefix)gcc |
AS = $(prefix)as |
LD = $(prefix)ld |
AR = $(prefix)ar |
RANLIB = $(prefix)ranlib |
OBJCOPY = $(prefix)objcopy |
OBJDUMP = $(prefix)objdump |
ifneq ($(GCC_VERSION),2) |
CFLAGS += -frename-registers |
endif |
CFLAGS += -mfixed-range=f32-f127 |
/branches/dd/boot/arch/ia64/loader/gefi/HelenOS/mkimage.c |
---|
File deleted |
/branches/dd/boot/arch/ia64/loader/gefi/HelenOS/division.c |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/dd/boot/arch/ia64/loader/gefi/HelenOS/division.h |
---|
File deleted |
\ No newline at end of file |
Property changes: |
Deleted: svn:special |
-* |
\ No newline at end of property |
/branches/dd/boot/arch/ia64/loader/gefi/HelenOS/Makefile |
---|
28,8 → 28,7 |
CRTOBJS = ../gnuefi/crt0-efi-$(ARCH).o |
LDSCRIPT = ../gnuefi/elf_$(ARCH)_efi.lds |
LDFLAGS += -T $(LDSCRIPT) -shared -Bsymbolic -L../lib -L../gnuefi $(CRTOBJS) |
#LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name) |
LOADLIBES = -lefi -lgnuefi |
LOADLIBES = -lefi -lgnuefi $(shell $(CC) -print-libgcc-file-name) |
FORMAT = efi-app-$(ARCH) |
37,7 → 36,7 |
clean: |
rm -f *.efi *~ *.o *.so *.map *.disass *.bin |
rm -f *.efi *~ *.o *.so |
.PHONY: install |
46,32 → 45,16 |
-j .rela -j .reloc --target=$(FORMAT) hello.so hello.efi |
$(OBJDUMP) -d hello.efi > hello.disass |
#When selected first lines or second lines, select if image is linked into hello or not - usefull for network boot |
#hello.so: hello.o image.o division.o |
hello.so: hello.o image.bin division.o |
# $(LD) $(LDFLAGS) -Map hello.map hello.o division.o image.o -o hello.so $(LOADLIBES) #link image inside hello |
$(LD) $(LDFLAGS) -Map hello.map hello.o division.o -o hello.so $(LOADLIBES) #dont link image inside hello |
hello.so: hello.o image.o |
$(LD) $(LDFLAGS) -Map hello.map hello.o -o hello.so $(LOADLIBES) |
hello.o: hello.c |
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c hello.c -o hello.o |
division.o: division.c |
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c division.c -o division.o |
image.bin: ../../image.boot |
image.o: ../../image.boot |
$(OBJCOPY) -O binary ../../image.boot image.bin |
$(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o |
image.o: ../../image.boot mkimage |
$(OBJCOPY) -O binary ../../image.boot image.bin |
./mkimage |
$(CC) $(INCDIR) $(CFLAGS) $(CPPFLAGS) -c image.c -o image.o |
# $(OBJCOPY) -I binary -O elf64-ia64-little -B ia64 image.bin image.o |
mkimage: mkimage.c |
gcc -o mkimage mkimage.c |
gefi: |
make -C .. prefix=$(PREFIX) |
/branches/dd/boot/arch/ia64/loader/gefi/HelenOS/hello.c |
---|
1,29 → 1,9 |
#include <efi.h> |
#include <efilib.h> |
#include <../../../../../../kernel/arch/ia64/include/bootinfo.h> |
#define KERNEL_LOAD_ADDRESS 0x4400000 |
#define MEM_MAP_DESCRIPTOR_OFFSET_TYPE 0 |
#define MEM_MAP_DESCRIPTOR_OFFSET_BASE 8 |
#define MEM_MAP_DESCRIPTOR_OFFSET_PAGES 24 |
//Link image as a data array into hello - usefull with network boot |
//#define IMAGE_LINKED |
bootinfo_t *bootinfo=(bootinfo_t *)BOOTINFO_ADDRESS; |
#ifdef IMAGE_LINKED |
extern char HOSimage[]; |
extern int HOSimagesize; |
#endif |
static CHAR16 * |
a2u (char *str) |
{ |
35,7 → 15,24 |
mem[i] = 0; |
return mem; |
} |
char HEX[256]; |
char hexs[]="0123456789ABCDEF"; |
/* |
void to_hex(unsigned long long num) |
{ |
int a; |
for(a=15;a>=0;a--) |
{ |
char c=num - (num & 0xfffffffffffffff0LL); |
num/=16; |
c=hexs[c]; |
HEX[a]=c; |
} |
} |
*/ |
EFI_STATUS |
efi_main (EFI_HANDLE image, EFI_SYSTEM_TABLE *systab) |
{ |
75,18 → 72,16 |
EFI_FILE *FileHandle; |
BS->HandleProtocol(LoadedImage->DeviceHandle, &FileSystemProtocol, &Vol); |
Vol->OpenVolume (Vol, &CurDir); |
char FileName[1024]; |
char *OsKernelBuffer; |
int i; |
int defaultLoad; |
int imageLoad; |
UINTN Size; |
StrCpy(FileName,DevicePathToStr(LoadedImage->FilePath)); |
for(i=StrLen(FileName);i>=0 && FileName[i]!='\\';i--); |
FileName[i] = 0; |
FileName[0] = 0; |
Print(L"%s\n",LoadedImage->LoadOptions); |
102,13 → 97,11 |
} |
while(LoadOptions[i]==L' ') if(LoadOptions[i++]==0) break; |
if(LoadOptions[i++]==0){ |
if(LoadOptions[i++]==0) |
StrCat(FileName,L"\\image.bin"); |
defaultLoad=1; |
} |
/* else{ |
else{ |
CHAR16 buf[1024]; |
//buf[0]='\\'; |
buf[0]='\\'; |
i--; |
int j; |
for(j=0;LoadOptions[i+j]!=L' '&&LoadOptions[i+j]!=0;j++) |
115,101 → 108,38 |
buf[j+1]=LoadOptions[i+j]; |
buf[j+1]=0; |
StrCat(FileName,buf); |
defaultLoad=0; |
}*/ |
else{ |
CHAR16 buf[1024]; |
//buf[0]='\\'; |
i--; |
int j; |
for(j=0;LoadOptions[i+j]!=L' '&&LoadOptions[i+j]!=0;j++) |
buf[j]=LoadOptions[i+j]; |
buf[j+1]=0; |
StrCat(FileName,buf); |
defaultLoad=0; |
} |
//Print(L"%s\n",FileName); |
imageLoad=1; |
#ifdef IMAGE_LINKED |
if(defaultLoad) { |
Print(L"Using Linked Image\n"); |
imageLoad=0; |
EFI_STATUS stat; |
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0); |
if(EFI_ERROR(stat)){ |
Print(L"Error Opening Image %s\n",FileName); |
return 0; |
} |
#endif |
Size = 0x00400000; |
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer); |
FileHandle->Read(FileHandle, &Size, OsKernelBuffer); |
FileHandle->Close(FileHandle); |
char * HOS; |
if(imageLoad) |
{ |
Size = 0x00400000; |
if(Size<1) return 0; |
Vol->OpenVolume (Vol, &CurDir); |
EFI_STATUS stat; |
stat=CurDir->Open(CurDir, &FileHandle, FileName, EFI_FILE_MODE_READ, 0); |
if(EFI_ERROR(stat)){ |
Print(L"Error Opening Image %s\n",FileName); |
return 0; |
} |
BS->AllocatePool(EfiLoaderData, Size, &OsKernelBuffer); |
FileHandle->Read(FileHandle, &Size, OsKernelBuffer); |
FileHandle->Close(FileHandle); |
HOS = OsKernelBuffer; |
if(Size<1) return 0; |
} |
#ifdef IMAGE_LINKED |
else { |
HOS = HOSimage; |
Size = HOSimagesize; |
Print(L"Image start %llX\n",(long long)HOS); |
Print(L"Image size %llX\n",(long long)Size); |
Print(L"Image &size %llX\n",(long long)&Size); |
} |
#endif |
char * HOS = OsKernelBuffer; |
int HOSSize = Size; |
rArg rSAL; |
rArg rPAL; |
//Setup AP's wake up address |
LibSalProc(0x01000000,2,0x4400200,0,0,0,0,0,&rSAL); |
//Get System Frequency |
UINT64 sys_freq; |
LibSalProc(0x01000012,0,0,0,0,0,0,0,&rSAL); |
sys_freq=rSAL.p1; |
UINT64 freq_scale; |
//Get CPU Frequency to System Frequency ratio |
LibPalProc(14,0,0,0,&rPAL); |
freq_scale=rPAL.p1; |
UINT64 sapic; |
LibGetSalIpiBlock(&sapic); |
Print (L"SAPIC:%X\n", sapic); |
//bootinfo->sapic=sapic; |
UINT64 wakeup_intno; |
LibGetSalWakeupVector(&wakeup_intno); |
Print (L"WAKEUP INTNO:%X\n", wakeup_intno); |
{ |
UINTN cookie; |
void *p=(void *)KERNEL_LOAD_ADDRESS; |
UINTN mapsize,descsize; |
UINT32 desver; |
EFI_STATUS status; |
EFI_MEMORY_DESCRIPTOR emd[1024]; |
mapsize=1024*sizeof(emd); |
status=BS->AllocatePages(AllocateAnyPages,EfiLoaderData,/*(HOSSize>>12)+1*/ 1,p); |
if(EFI_ERROR(status)){ |
220,18 → 150,10 |
return EFI_SUCCESS; |
} |
UINTN no_entryes; |
void * mds; |
mds=LibMemoryMap(&no_entryes,&cookie,&descsize,&desver); |
for(i=0;i<no_entryes;i++) |
{ |
unsigned int type=*((unsigned int *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_TYPE)); |
unsigned long long base=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_BASE)); |
unsigned long long pages=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_PAGES)); |
Print(L"T:%02d %016llX %016llX\n",type,base,pages*EFI_PAGE_SIZE); |
status=BS->GetMemoryMap(&mapsize,emd,&cookie,&descsize,&desver); |
if(EFI_ERROR(status)){ |
Print(L"Error 1\n"); |
return EFI_SUCCESS; |
} |
status=BS->ExitBootServices(image,cookie); |
if(EFI_ERROR(status)){ |
239,62 → 161,12 |
return EFI_SUCCESS; |
} |
} |
int a; |
for(a=0;a<HOSSize;a++){ |
((char *)(0x4400000))[a]=HOS[a]; |
} |
bootinfo->sapic=(unsigned long *)sapic; |
bootinfo->wakeup_intno=wakeup_intno; |
bootinfo->sys_freq=sys_freq; |
bootinfo->freq_scale=freq_scale; |
bootinfo->hello_configured=1; |
bootinfo->memmap_items=0; |
for(i=0;i<no_entryes;i++) |
{ |
unsigned int type=*((unsigned int *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_TYPE)); |
unsigned long long base=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_BASE)); |
unsigned long long pages=*((unsigned long long *)(mds+i*descsize+MEM_MAP_DESCRIPTOR_OFFSET_PAGES)); |
switch (type) |
{ |
case EfiConventionalMemory: |
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_FREE_MEM; |
bootinfo->memmap[bootinfo->memmap_items].base=base; |
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE; |
bootinfo->memmap_items++; |
break; |
case EfiMemoryMappedIO: |
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_IO; |
bootinfo->memmap[bootinfo->memmap_items].base=base; |
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE; |
bootinfo->memmap_items++; |
break; |
case EfiMemoryMappedIOPortSpace: |
bootinfo->memmap[bootinfo->memmap_items].type=EFI_MEMMAP_IO_PORTS; |
bootinfo->memmap[bootinfo->memmap_items].base=base; |
bootinfo->memmap[bootinfo->memmap_items].size=pages*EFI_PAGE_SIZE; |
bootinfo->memmap_items++; |
break; |
default : |
break; |
} |
} |
//Run Kernel |
asm volatile( |
305,6 → 177,8 |
); |
//Not reached |
while(1){ |
((volatile int *)(0x80000000000b8000))[0]++; |
} |
return EFI_SUCCESS; |
} |
/branches/dd/boot/arch/ia64/loader/gefi/Makefile |
---|
23,9 → 23,9 |
include Make.defaults |
SUBDIRS = lib gnuefi inc |
SUBDIRS = lib gnuefi inc apps |
all: $(SUBDIRS) |
all: check_gcc $(SUBDIRS) |
$(SUBDIRS): |
$(MAKE) -C $@ |
39,4 → 39,13 |
.PHONY: $(SUBDIRS) clean depend |
# |
# on both platforms you must use gcc 3.0 or higher |
# |
check_gcc: |
ifeq ($(GCC_VERSION),2) |
@echo "you need to use a version of gcc >= 3.0, you are using `$(CC) --version`" |
@exit 1 |
endif |
include Make.rules |
/branches/dd/boot/arch/ia64/loader/Makefile |
---|
27,19 → 27,13 |
# |
include ../../../../version |
-include ../../../../Makefile.config |
include ../../../Makefile.config |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-ia64-little |
BFD_ARCH = ia64 |
TARGET = ia64-pc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ia64/bin |
TOOLCHAIN_DIR = /usr/local/ia64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
47,7 → 41,7 |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
GEFI_PREFIX = |
GEFI_PREXIX = |
endif |
ifeq ($(COMPILER),icc_native) |
68,48 → 62,40 |
endif |
#-mno-pic means do not use gp + imm22 to address data |
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic -pipe |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -I../../../../kernel/generic/include -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -fno-unwind-tables -mfixed-range=f32-f127 -mno-pic |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
SOURCES = \ |
main.c \ |
../../../generic/printf.c \ |
../../../generic/string.c \ |
../../../genarch/balloc.c \ |
_components.c \ |
asm.S \ |
boot.S |
NOCOMPONENTS = \ |
$(KERNELDIR)/kernel.bin |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
119,44 → 105,25 |
-include Makefile.depend |
hello.efi: image.boot |
make -C gefi/HelenOS PREFIX=$(GEFI_PREFIX) |
cp gefi/HelenOS/hello.efi ../../../../ |
# cp gefi/HelenOS/hello.efi /boot/efi/ |
cp gefi/HelenOS/image.bin ../../../../ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -Map boot.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) image.boot image.map image.disasm initrd.img image.boot Makefile.depend ../../../../image.bin ../../../../hello.efi |
make -C gefi clean |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot boot.disasm Makefile.depend |
make -C gefi/HelenOS clean |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned long" $(COMPONENTS) ./initrd.img |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(IMAGE) $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
165,4 → 132,4 |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
disasm: image.boot |
$(OBJDUMP) -d image.boot > image.disasm |
$(OBJDUMP) -d image.boot > boot.disasm |
/branches/dd/boot/arch/ia64/loader/boot.S |
---|
34,7 → 34,6 |
.global start |
start: |
mov ar.rsc = r0 |
# movl r8 = (VRN_KERNEL << VRN_SHIFT) ;; |
movl r1 = 0x4400000 |
58,22 → 57,6 |
mov b1 = r18 ;; |
br.call.sptk.many b0 = b1 |
.align 512 |
ap_start: |
ap_loop: |
movl r18=0x4405000;; |
mov b1 = r18 ;; |
br.call.sptk.many b0 = b1;; |
.align 1024 |
.align 4096 |
.global binfo |
binfo: |
.bss #on this line is ".bss", it cannot be seen in my mcedit :-( |
/branches/dd/boot/arch/ia64/loader/pack |
---|
0,0 → 1,121 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift |
echo 'OUTPUT_FORMAT("elf64-ia64-little") |
ENTRY(start) |
SECTIONS { |
.boot 0x4400000: AT (0x4400000) { |
*(BOOTSTRAP); |
. = ALIGN (0x4000); |
' > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned int size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
*(.${BASENAME}_image); |
. = ALIGN (0x4000);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned long) ${MACRO}_END - (unsigned long) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf64-ia64-little -B ia64 --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
_got = . ; |
*(.got .got.*); |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON);' >> "$LINK" |
echo ' } |
/DISCARD/ : { |
*(.comment); |
*(.note*); |
} |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
static void init_components(component_t components[]) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/ia64/loader/asm.S |
---|
37,5 → 37,7 |
alloc loc0 = ar.pfs, 1, 1, 0, 0 |
movl r8 = 0x4404000;; |
mov b1 = r8 ;; |
mov r1 = in0; #Save bootinfo prt |
mov r1 = in0; |
br.call.sptk.many b0 = b1;; |
.global ofw |
ofw: |
/branches/dd/boot/arch/ia64/loader/main.c |
---|
1,6 → 1,6 |
/* |
* Copyright (c) 2005 Martin Decky |
* Copyright (c) 2006 Jakub Jermar |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
33,13 → 33,11 |
#include "_components.h" |
#include <align.h> |
#include <balloc.h> |
#include <macros.h> |
#include <string.h> |
extern bootinfo_t binfo; |
bootinfo_t bootinfo; |
component_t components[COMPONENTS]; |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
void write(const char *str, const int len) |
{ |
46,22 → 44,15 |
return; |
} |
#define DEFAULT_MEMORY_BASE 0x4000000 |
#define DEFAULT_MEMORY_SIZE 0x4000000 |
#define DEFAULT_LEGACY_IO_BASE 0x00000FFFFC000000 |
#define DEFAULT_LEGACY_IO_SIZE 0x4000000 |
#define DEFAULT_FREQ_SCALE 0x0000000100000001 /* 1/1 */ |
#define DEFAULT_SYS_FREQ 100000000 /* 100MHz */ |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
69,18 → 60,26 |
/** Print version information. */ |
static void version_print(void) |
{ |
printf("HelenOS IA64 Bootloader\nRelease %s%s%s\n" |
"Copyright (c) 2006 HelenOS project\n", release, revision, |
timestamp); |
printf("HelenOS IA64 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp); |
} |
void bootstrap(void) |
{ |
int ii; |
bootinfo_t *bootinfo = &binfo; |
//for(ii=0;ii<KERNEL_SIZE;ii++) ((char *)(0x100000))[ii] = ((char *)KERNEL_START)[ii+1]; |
//((int *)(0x100000))[0]++; |
version_print(); |
init_components(components); |
printf("\nSystem info\n"); |
92,46 → 91,20 |
printf(" %P: %s image (size %d bytes)\n", components[i].start, |
components[i].name, components[i].size); |
if (!bootinfo->hello_configured) { |
/* |
* Load configuration defaults for simulators. |
*/ |
bootinfo->memmap_items = 0; |
bootinfo->memmap[bootinfo->memmap_items].base = |
DEFAULT_MEMORY_BASE; |
bootinfo->memmap[bootinfo->memmap_items].size = |
DEFAULT_MEMORY_SIZE; |
bootinfo->memmap[bootinfo->memmap_items].type = |
EFI_MEMMAP_FREE_MEM; |
bootinfo->memmap_items++; |
bootinfo->memmap[bootinfo->memmap_items].base = |
DEFAULT_LEGACY_IO_BASE; |
bootinfo->memmap[bootinfo->memmap_items].size = |
DEFAULT_LEGACY_IO_SIZE; |
bootinfo->memmap[bootinfo->memmap_items].type = |
EFI_MEMMAP_IO_PORTS; |
bootinfo->memmap_items++; |
bootinfo->freq_scale = DEFAULT_FREQ_SCALE; |
bootinfo->sys_freq = DEFAULT_SYS_FREQ; |
} |
bootinfo.taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
bootinfo->taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
if (i > 0) { |
bootinfo->taskmap.tasks[bootinfo->taskmap.count].addr = |
components[i].start; |
bootinfo->taskmap.tasks[bootinfo->taskmap.count].size = |
components[i].size; |
strncpy(bootinfo->taskmap.tasks[ |
bootinfo->taskmap.count].name, |
components[i].name, BOOTINFO_TASK_NAME_BUFLEN); |
bootinfo->taskmap.count++; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = components[i].start; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size; |
bootinfo.taskmap.count++; |
} |
} |
jump_to_kernel(bootinfo); |
jump_to_kernel(&bootinfo); |
} |
/branches/dd/boot/arch/ia64/loader/main.h |
---|
29,14 → 29,29 |
#ifndef BOOT_ia64_MAIN_H_ |
#define BOOT_ia64_MAIN_H_ |
#include <ofw.h> |
#include <ofw_tree.h> |
#include <types.h> |
#include <../../../../kernel/arch/ia64/include/bootinfo.h> |
#define CONFIG_INIT_TASKS 32 |
typedef struct { |
void *addr; |
size_t size; |
} init_task_t; |
typedef struct { |
count_t count; |
init_task_t tasks[CONFIG_INIT_TASKS]; |
} init_t; |
typedef struct { |
init_t taskmap; |
} bootinfo_t; |
extern bootinfo_t bootinfo; |
extern void start(void); |
extern void bootstrap(void); |
/branches/dd/boot/arch/ia64/Makefile.inc |
---|
26,17 → 26,39 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#ifeq ($(MACHINE),ski) |
#VMAXLMA_SRC = tools/ia64/vmaxlma.c |
#build: $(BASE)/kernel.bin |
#echo Building SKI |
#$(BASE)/kernel.bin: $(KERNELDIR)/kernel.bin vmaxlma |
# cp $(KERNELDIR)/kernel.bin $(BASE)/kernel.bin |
# ./vmaxlma $(BASE)/kernel.bin |
#vmaxlma: $(VMAXLMA_SRC) |
# $(CC) $(VMAXLMA_SRC) -o $@ |
#clean: |
# -rm -f $(BASE)/kernel.bin vmaxlma |
#else |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot |
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot |
depend: |
-rm arch/$(BARCH)/loader/image.boot |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(BARCH)/loader/image.boot: |
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
clean: generic_clean |
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
-rm -f $(BASE)/image.boot |
#endif |
/branches/dd/boot/arch/sparc64/loader/_link.ld.in |
---|
File deleted |
/branches/dd/boot/arch/sparc64/loader/Makefile |
---|
27,19 → 27,13 |
# |
include ../../../../version |
-include ../../../../Makefile.config |
include ../../../Makefile.config |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf64-sparc |
BFD_ARCH = sparc |
TARGET = sparc64-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/sparc64/bin |
TOOLCHAIN_DIR = /usr/local/sparc64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
49,6 → 43,14 |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),icc_native) |
CC = icc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),gcc_cross) |
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc |
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as |
57,11 → 59,18 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 -mno-fpu -pipe |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=ultrasparc -m64 |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
SOURCES = \ |
main.c \ |
_components.c \ |
../../../generic/printf.c \ |
../../../generic/string.c \ |
../../../genarch/balloc.c \ |
71,50 → 80,23 |
asm.S \ |
boot.S |
# |
# All components that go to image.boot without the ramdisk. |
# |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
# |
# Final list of all components that go to image.boot. |
# |
ALL_COMPONENTS = $(COMPONENTS) |
ifeq ($(CONFIG_RD_EXTERNAL),n) |
ALL_COMPONENTS += ./initrd.img |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/fhc/fhc \ |
$(USPACEDIR)/srv/obio/obio |
RD_APPS = \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/bdsh/bdsh \ |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
ALL_COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(ALL_COMPONENTS)))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
.PHONY: all clean depend |
122,37 → 104,17 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -Map image.map -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS) $(OBJECTS) initrd.img image.boot image.map image.disasm Makefile.depend |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot boot.disasm Makefile.depend |
_components.h _components.c _link.ld $(ALL_COMPONENT_OBJECTS): $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 1 "unsigned long" $(ALL_COMPONENTS) |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(IMAGE) $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
161,4 → 123,4 |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
disasm: image.boot |
$(OBJDUMP) -d image.boot > image.disasm |
$(OBJDUMP) -d image.boot > boot.disasm |
/branches/dd/boot/arch/sparc64/loader/pack |
---|
0,0 → 1,113 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift |
echo 'OUTPUT_FORMAT("elf64-sparc") |
ENTRY(start) |
SECTIONS { |
.boot 0x4000: AT (0x4000) { |
*(BOOTSTRAP); |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON);' > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned int size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned long) ${MACRO}_END - (unsigned long) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf64-sparc -B sparc --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' } |
/DISCARD/ : { |
*(.comment); |
*(.note*); |
} |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
static void init_components(component_t components[]) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/sparc64/loader/main.c |
---|
36,87 → 36,34 |
#include <ofw_tree.h> |
#include "ofwarch.h" |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
bootinfo_t bootinfo; |
component_t components[COMPONENTS]; |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
/** UltraSPARC subarchitecture - 1 for US, 3 for US3 */ |
uint8_t subarchitecture; |
/** |
* mask of the MID field inside the ICBUS_CONFIG register shifted by |
* MID_SHIFT bits to the right |
*/ |
uint16_t mid_mask; |
/** Print version information. */ |
static void version_print(void) |
{ |
printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\n" |
"Copyright (c) 2006 HelenOS project\n", |
release, revision, timestamp); |
printf("HelenOS SPARC64 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp); |
} |
/* the lowest ID (read from the VER register) of some US3 CPU model */ |
#define FIRST_US3_CPU 0x14 |
/* the greatest ID (read from the VER register) of some US3 CPU model */ |
#define LAST_US3_CPU 0x19 |
/* UltraSPARC IIIi processor implementation code */ |
#define US_IIIi_CODE 0x15 |
/** |
* Sets the global variables "subarchitecture" and "mid_mask" to |
* correct values. |
*/ |
static void detect_subarchitecture(void) |
{ |
uint64_t v; |
asm volatile ("rdpr %%ver, %0\n" : "=r" (v)); |
v = (v << 16) >> 48; |
if ((v >= FIRST_US3_CPU) && (v <= LAST_US3_CPU)) { |
subarchitecture = SUBARCH_US3; |
if (v == US_IIIi_CODE) |
mid_mask = (1 << 5) - 1; |
else |
mid_mask = (1 << 10) - 1; |
} else if (v < FIRST_US3_CPU) { |
subarchitecture = SUBARCH_US; |
mid_mask = (1 << 5) - 1; |
} else { |
printf("\nThis CPU is not supported by HelenOS."); |
} |
} |
void bootstrap(void) |
{ |
void *base = (void *) KERNEL_VIRTUAL_ADDRESS; |
void *balloc_base; |
unsigned int top = 0; |
int i, j; |
version_print(); |
detect_subarchitecture(); |
init_components(components); |
if (!ofw_get_physmem_start(&bootinfo.physmem_start)) { |
128,103 → 75,34 |
printf("Error: unable to get memory map, halting.\n"); |
halt(); |
} |
if (bootinfo.memmap.total == 0) { |
printf("Error: no memory detected, halting.\n"); |
halt(); |
} |
/* |
* SILO for some reason adds 0x400000 and subtracts |
* bootinfo.physmem_start to/from silo_ramdisk_image. |
* We just need plain physical address so we fix it up. |
*/ |
if (silo_ramdisk_image) { |
silo_ramdisk_image += bootinfo.physmem_start; |
silo_ramdisk_image -= 0x400000; |
/* Install 1:1 mapping for the ramdisk. */ |
if (ofw_map((void *)((uintptr_t) silo_ramdisk_image), |
(void *)((uintptr_t) silo_ramdisk_image), |
silo_ramdisk_size, -1) != 0) { |
printf("Failed to map ramdisk.\n"); |
halt(); |
} |
} |
printf("\nSystem info\n"); |
printf(" memory: %dM starting at %P\n", |
bootinfo.memmap.total >> 20, bootinfo.physmem_start); |
bootinfo.memmap.total >> 20, bootinfo.physmem_start); |
printf("\nMemory statistics\n"); |
printf(" kernel entry point at %P\n", KERNEL_VIRTUAL_ADDRESS); |
printf(" %P: boot info structure\n", &bootinfo); |
/* |
* Figure out destination address for each component. |
* In this phase, we don't copy the components yet because we want to |
* to be careful not to overwrite anything, especially the components |
* which haven't been copied yet. |
*/ |
bootinfo.taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
printf(" %P: %s image (size %d bytes)\n", components[i].start, |
components[i].name, components[i].size); |
top = ALIGN_UP(top, PAGE_SIZE); |
if (i > 0) { |
if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) { |
printf("Skipping superfluous components.\n"); |
break; |
} |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
components[i].size; |
strncpy(bootinfo.taskmap.tasks[ |
bootinfo.taskmap.count].name, components[i].name, |
BOOTINFO_TASK_NAME_BUFLEN); |
bootinfo.taskmap.count++; |
} |
top += components[i].size; |
} |
j = bootinfo.taskmap.count - 1; /* do not consider ramdisk */ |
void * base = (void *) KERNEL_VIRTUAL_ADDRESS; |
unsigned int top = 0; |
if (silo_ramdisk_image) { |
/* Treat the ramdisk as the last bootinfo task. */ |
if (bootinfo.taskmap.count == TASKMAP_MAX_RECORDS) { |
printf("Skipping ramdisk.\n"); |
goto skip_ramdisk; |
} |
printf("\nCopying components\n"); |
bootinfo.taskmap.count = 0; |
for (i = 0; i < COMPONENTS; i++) { |
printf(" %s...", components[i].name); |
top = ALIGN_UP(top, PAGE_SIZE); |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
silo_ramdisk_size; |
bootinfo.taskmap.count++; |
printf("\nCopying ramdisk..."); |
/* |
* Claim and map the whole ramdisk as it may exceed the area |
* given to us by SILO. |
*/ |
(void) ofw_claim_phys(base + top, silo_ramdisk_size); |
(void) ofw_map(bootinfo.physmem_start + base + top, base + top, |
silo_ramdisk_size, -1); |
memmove(base + top, (void *)((uintptr_t)silo_ramdisk_image), |
silo_ramdisk_size); |
printf("done.\n"); |
top += silo_ramdisk_size; |
} |
skip_ramdisk: |
/* |
* Now we can proceed to copy the components. We do it in reverse order |
* so that we don't overwrite anything even if the components overlap |
* with base. |
*/ |
printf("\nCopying bootinfo tasks\n"); |
for (i = COMPONENTS - 1; i > 0; i--, j--) { |
printf(" %s...", components[i].name); |
/* |
* At this point, we claim the physical memory that we are |
* going to use. We should be safe in case of the virtual |
232,41 → 110,36 |
* SPARC binding, should restrict its use of virtual memory |
* to addresses from [0xffd00000; 0xffefffff] and |
* [0xfe000000; 0xfeffffff]. |
* |
* XXX We don't map this piece of memory. We simply rely on |
* SILO to have it done for us already in this case. |
*/ |
(void) ofw_claim_phys(bootinfo.physmem_start + |
bootinfo.taskmap.tasks[j].addr, |
(void) ofw_claim_phys(bootinfo.physmem_start + base + top, |
ALIGN_UP(components[i].size, PAGE_SIZE)); |
memcpy((void *)bootinfo.taskmap.tasks[j].addr, |
components[i].start, components[i].size); |
memcpy(base + top, components[i].start, components[i].size); |
if (i > 0) { |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = |
base + top; |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = |
components[i].size; |
bootinfo.taskmap.count++; |
} |
top += components[i].size; |
printf("done.\n"); |
} |
printf("\nCopying kernel..."); |
(void) ofw_claim_phys(bootinfo.physmem_start + base, |
ALIGN_UP(components[0].size, PAGE_SIZE)); |
memcpy(base, components[0].start, components[0].size); |
printf("done.\n"); |
/* |
* Claim and map the physical memory for the boot allocator. |
* Claim the physical memory for the boot allocator. |
* Initialize the boot allocator. |
*/ |
balloc_base = base + ALIGN_UP(top, PAGE_SIZE); |
(void) ofw_claim_phys(bootinfo.physmem_start + balloc_base, |
BALLOC_MAX_SIZE); |
(void) ofw_map(bootinfo.physmem_start + balloc_base, balloc_base, |
BALLOC_MAX_SIZE, -1); |
balloc_init(&bootinfo.ballocs, (uintptr_t)balloc_base); |
(void) ofw_claim_phys(bootinfo.physmem_start + |
base + ALIGN_UP(top, PAGE_SIZE), BALLOC_MAX_SIZE); |
balloc_init(&bootinfo.ballocs, ALIGN_UP(((uintptr_t) base) + top, |
PAGE_SIZE)); |
printf("\nCanonizing OpenFirmware device tree..."); |
bootinfo.ofw_root = ofw_tree_build(); |
printf("done.\n"); |
#ifdef CONFIG_AP |
#ifdef CONFIG_SMP |
printf("\nChecking for secondary processors..."); |
if (!ofw_cpu()) |
printf("Error: unable to get CPU properties\n"); |
273,10 → 146,9 |
printf("done.\n"); |
#endif |
ofw_setup_palette(); |
printf("\nBooting the kernel...\n"); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | BSP_PROCESSOR, &bootinfo, |
sizeof(bootinfo)); |
} |
/branches/dd/boot/arch/sparc64/loader/ofwarch.c |
---|
32,7 → 32,7 |
* @brief Architecture dependent parts of OpenFirmware interface. |
*/ |
#include <ofwarch.h> |
#include <ofwarch.h> |
#include <ofw.h> |
#include <printf.h> |
#include <string.h> |
40,10 → 40,6 |
#include "main.h" |
#include "asm.h" |
/* these tho variables will be set by the detect_subarchitecture function */ |
extern uint8_t subarchitecture; |
extern uint16_t mid_mask; |
void write(const char *str, const int len) |
{ |
int i; |
60,40 → 56,31 |
return flag != -1; |
} |
/** |
* Starts all CPUs represented by following siblings of the given node, |
* except for the current CPU. |
* |
* @param child The first child of the OFW tree node whose children |
* represent CPUs to be woken up. |
* @param current_mid MID of the current CPU, the current CPU will |
* (of course) not be woken up. |
* @return Number of CPUs which have the same parent node as |
* "child". |
*/ |
static int wake_cpus_in_node(phandle child, uint64_t current_mid) |
int ofw_cpu(void) |
{ |
int cpus; |
char type_name[BUF_SIZE]; |
phandle node; |
node = ofw_get_child_node(ofw_root); |
if (node == 0 || node == -1) { |
printf("Could not find any child nodes of the root node.\n"); |
return 0; |
} |
for (cpus = 0; child != 0 && child != -1; |
child = ofw_get_peer_node(child), cpus++) { |
if (ofw_get_property(child, "device_type", type_name, |
sizeof(type_name)) > 0) { |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" : "=r" (current_mid) : "r" (0), "i" (ASI_UPA_CONFIG)); |
current_mid >>= UPA_CONFIG_MID_SHIFT; |
current_mid &= UPA_CONFIG_MID_MASK; |
int cpus; |
for (cpus = 0; node != 0 && node != -1; node = ofw_get_peer_node(node), cpus++) { |
if (ofw_get_property(node, "device_type", type_name, sizeof(type_name)) > 0) { |
if (strcmp(type_name, "cpu") == 0) { |
uint32_t mid; |
/* |
* "upa-portid" for US, "portid" for US-III, |
* "cpuid" for US-IV |
*/ |
if (ofw_get_property( |
child, "upa-portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "portid", |
&mid, sizeof(mid)) <= 0 |
&& ofw_get_property(child, "cpuid", |
&mid, sizeof(mid)) <= 0) |
if (ofw_get_property(node, "upa-portid", &mid, sizeof(mid)) <= 0) |
continue; |
if (current_mid != mid) { |
100,10 → 87,9 |
/* |
* Start secondary processor. |
*/ |
(void) ofw_call("SUNW,start-cpu", 3, 1, |
NULL, child, KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | |
AP_PROCESSOR); |
(void) ofw_call("SUNW,start-cpu", 3, 1, NULL, node, |
KERNEL_VIRTUAL_ADDRESS, |
bootinfo.physmem_start | AP_PROCESSOR); |
} |
} |
} |
112,59 → 98,12 |
return cpus; |
} |
/** |
* Finds out the current CPU's MID and wakes up all AP processors. |
*/ |
int ofw_cpu(void) |
{ |
int cpus; |
phandle node; |
phandle subnode; |
phandle cpus_parent; |
phandle cmp; |
char name[BUF_SIZE]; |
/* get the current CPU MID */ |
uint64_t current_mid; |
asm volatile ("ldxa [%1] %2, %0\n" |
: "=r" (current_mid) |
: "r" (0), "i" (ASI_ICBUS_CONFIG)); |
current_mid >>= ICBUS_CONFIG_MID_SHIFT; |
current_mid &= mid_mask; |
/* wake up CPUs */ |
cpus_parent = ofw_find_device("/ssm@0,0"); |
if (cpus_parent == 0 || cpus_parent == -1) { |
cpus_parent = ofw_find_device("/"); |
} |
node = ofw_get_child_node(cpus_parent); |
cpus = wake_cpus_in_node(node, current_mid); |
while (node != 0 && node != -1) { |
if (ofw_get_property(node, "name", name, |
sizeof(name)) > 0) { |
if (strcmp(name, "cmp") == 0) { |
subnode = ofw_get_child_node(node); |
cpus += wake_cpus_in_node(subnode, |
current_mid); |
} |
} |
node = ofw_get_peer_node(node); |
} |
return cpus; |
} |
/** Get physical memory starting address. |
* |
* @param start Pointer to variable where the physical memory starting |
* address will be stored. |
* @param start Pointer to variable where the physical memory starting |
* address will be stored. |
* |
* @return Non-zero on succes, zero on failure. |
* @return Non-zero on succes, zero on failure. |
*/ |
int ofw_get_physmem_start(uintptr_t *start) |
{ |
/branches/dd/boot/arch/sparc64/loader/asm.S |
---|
30,9 → 30,6 |
#include <stack.h> |
#include <register.h> |
.register %g2, #scratch |
.register %g3, #scratch |
.text |
.global halt |
44,7 → 41,8 |
nop |
memcpy: |
mov %o0, %o3 ! save dst |
.register %g2, #scratch |
.register %g3, #scratch |
add %o1, 7, %g1 |
and %g1, -8, %g1 |
cmp %o1, %g1 |
63,7 → 61,7 |
mov %g2, %g3 |
2: |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
3: |
and %g1, -8, %g1 |
cmp %o0, %g1 |
97,38 → 95,9 |
mov %g2, %g3 |
jmp %o7 + 8 ! exit point |
mov %o3, %o0 |
mov %o1, %o0 |
jump_to_kernel: |
/* |
* We have copied code and now we need to guarantee cache coherence. |
* 1. Make sure that the code we have moved has drained to main memory. |
* 2. Invalidate I-cache. |
* 3. Flush instruction pipeline. |
*/ |
/* |
* US3 processors have a write-invalidate cache, so explicitly |
* invalidating it is not required. Whether to invalidate I-cache |
* or not is decided according to the value of the global |
* "subarchitecture" variable (set in the bootstrap). |
*/ |
set subarchitecture, %g2 |
ldub [%g2], %g2 |
cmp %g2, 3 |
be 1f |
nop |
0: |
call icache_flush |
nop |
1: |
membar #StoreStore |
/* |
* Flush the instruction pipeline. |
*/ |
flush %i7 |
mov %o0, %l1 |
mov %o1, %o0 |
mov %o2, %o1 |
136,23 → 105,6 |
jmp %l1 ! jump to kernel |
nop |
#define ICACHE_SIZE 8192 |
#define ICACHE_LINE_SIZE 32 |
#define ICACHE_SET_BIT (1 << 13) |
#define ASI_ICACHE_TAG 0x67 |
# Flush I-cache |
icache_flush: |
set ((ICACHE_SIZE - ICACHE_LINE_SIZE) | ICACHE_SET_BIT), %g1 |
stxa %g0, [%g1] ASI_ICACHE_TAG |
0: membar #Sync |
subcc %g1, ICACHE_LINE_SIZE, %g1 |
bnz,pt %xcc, 0b |
stxa %g0, [%g1] ASI_ICACHE_TAG |
membar #Sync |
retl |
! SF Erratum #51 |
nop |
.global ofw |
ofw: |
save %sp, -STACK_WINDOW_SAVE_AREA_SIZE, %sp |
/branches/dd/boot/arch/sparc64/loader/boot.S |
---|
53,15 → 53,6 |
.ascii "HdrS" |
.word 0 |
.half 0 |
.half 0 |
.half 0 |
.half 0 |
.global silo_ramdisk_image |
silo_ramdisk_image: |
.word 0 |
.global silo_ramdisk_size |
silo_ramdisk_size: |
.word 0 |
.align 8 |
1: |
/branches/dd/boot/arch/sparc64/loader/main.h |
---|
38,19 → 38,12 |
#define TASKMAP_MAX_RECORDS 32 |
/** Size of buffer for storing task name in task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
#define BSP_PROCESSOR 1 |
#define AP_PROCESSOR 0 |
#define SUBARCH_US 1 |
#define SUBARCH_US3 3 |
typedef struct { |
void *addr; |
uint32_t size; |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} task_t; |
typedef struct { |
66,9 → 59,6 |
ofw_tree_node_t *ofw_root; |
} bootinfo_t; |
extern uint32_t silo_ramdisk_image; |
extern uint32_t silo_ramdisk_size; |
extern bootinfo_t bootinfo; |
extern void start(void); |
/branches/dd/boot/arch/sparc64/loader/register.h |
---|
33,7 → 33,8 |
#define PSTATE_PRIV_BIT 4 |
#define PSTATE_AM_BIT 8 |
#define ASI_ICBUS_CONFIG 0x4a |
#define ICBUS_CONFIG_MID_SHIFT 17 |
#define ASI_UPA_CONFIG 0x4a |
#define UPA_CONFIG_MID_SHIFT 17 |
#define UPA_CONFIG_MID_MASK 0x1f |
#endif |
/branches/dd/boot/arch/sparc64/silo/silo.patched.tar.gz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Deleted: svn:mime-type |
-application/octet-stream |
\ No newline at end of property |
/branches/dd/boot/arch/sparc64/silo/silo.conf |
---|
1,4 → 1,3 |
timeout = 0 |
image = /HelenOS/image.boot.gz |
image = /HelenOS/image.boot |
label = HelenOS |
initrd = /HelenOS/initrd.img |
/branches/dd/boot/arch/sparc64/Makefile.inc |
---|
26,40 → 26,25 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
TMP = distroot |
TMP=distroot |
ifeq ($(CONFIG_AOUT_ISOFS_B),y) |
SILO_PACKAGE = silo.tar.gz |
else |
SILO_PACKAGE = silo.patched.tar.gz |
endif |
build: $(BASE)/image.iso |
$(BASE)/image.iso: depend arch/$(BARCH)/loader/image.boot |
$(BASE)/image.iso: depend arch/$(ARCH)/loader/image.boot |
mkdir -p $(TMP)/boot |
mkdir -p $(TMP)/HelenOS |
cat arch/$(BARCH)/silo/$(SILO_PACKAGE) | (cd $(TMP)/boot; tar xvfz -) |
cp arch/$(BARCH)/silo/README arch/$(BARCH)/silo/COPYING $(TMP)/boot |
ifeq ($(CONFIG_RD_EXTERNAL),y) |
cp arch/$(BARCH)/silo/silo.conf $(TMP)/boot/silo.conf |
else |
cat arch/$(BARCH)/silo/silo.conf | grep -v initrd > $(TMP)/boot/silo.conf |
endif |
cp arch/$(BARCH)/loader/image.boot $(TMP)/HelenOS/image.boot |
gzip -f $(TMP)/HelenOS/image.boot |
ifeq ($(CONFIG_RD_EXTERNAL),y) |
cp arch/$(BARCH)/loader/initrd.img $(TMP)/HelenOS/initrd.img |
endif |
cat arch/$(ARCH)/silo/silo.tar.gz | (cd $(TMP)/boot; tar xvfz -) |
cp arch/$(ARCH)/silo/README arch/$(ARCH)/silo/COPYING arch/$(ARCH)/silo/silo.conf $(TMP)/boot |
cp arch/$(ARCH)/loader/image.boot $(TMP)/HelenOS/image.boot |
mkisofs -f -G $(TMP)/boot/isofs.b -B ... -r -o $(BASE)/image.iso $(TMP)/ |
depend: |
-rm arch/$(BARCH)/loader/image.boot |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(BARCH)/loader/image.boot: |
$(MAKE) -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
arch/$(ARCH)/loader/image.boot: |
$(MAKE) -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
clean: generic_clean |
$(MAKE) -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
$(MAKE) -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
-rm -fr $(TMP) |
-rm -f $(BASE)/image.iso |
/branches/dd/boot/arch/arm32/loader/_link.ld.in |
---|
File deleted |
/branches/dd/boot/arch/arm32/loader/Makefile |
---|
27,29 → 27,21 |
# |
include ../../../../version |
-include ../../../../Makefile.config |
include ../../../../Makefile.config |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-littlearm |
BFD_ARCH = arm |
TARGET = arm-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/arm/bin |
TOOLCHAIN_DIR = /usr/local/arm/bin |
ifeq ($(COMPILER),gcc_native) |
ifeq ($(COMPILER),native) |
CC = gcc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),gcc_cross) |
else |
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc |
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as |
LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld |
57,47 → 49,47 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../.. -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -pipe |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../.. -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
ifdef MACHINE |
CFLAGS += "-DMACHINE=$(MACHINE)" |
endif |
SOURCES = \ |
main.c \ |
boot.S \ |
asm.S \ |
mm.c \ |
print/gxemul.c \ |
_components.c \ |
../../../generic/printf.c \ |
../../../generic/string.c \ |
../../../genarch/division.c |
ifeq ($(MACHINE), gxemul_testarm) |
SOURCES += print/gxemul.c |
endif |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
$(USPACEDIR)/app/tetris/tetris |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
108,37 → 100,17 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(OBJECTS) $(COMPONENT_OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(IMAGE) $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/boot/arch/arm32/loader/asm.h |
---|
32,7 → 32,7 |
*/ |
/** @file |
* @brief Functions implemented in assembly. |
*/ |
*/ |
#ifndef BOOT_arm32_ASM_H |
40,10 → 40,10 |
/** Copies cnt bytes from dst to src. |
* |
* |
* @param dst Destination address. |
* @param src Source address. |
* @param cnt Count of bytes to be copied. |
* @param cnt Count of bytes to be copied. |
*/ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
58,11 → 58,12 |
/** Jumps to the kernel entry point. |
* |
* @param entry Kernel entry point address. |
* @param bootinfo Structure holding information about loaded tasks. |
* |
* @param entry Kernel entry point address. |
* @param bootinfo Structure holding information about loaded tasks. |
* @param bootinfo_size Size of the bootinfo structure. |
*/ |
extern void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn)); |
extern void jump_to_kernel(void *entry, void *bootinfo, |
unsigned int bootinfo_size) __attribute__((noreturn)); |
#endif |
/branches/dd/boot/arch/arm32/loader/main.h |
---|
32,7 → 32,7 |
*/ |
/** @file |
* @brief Boot related declarations. |
*/ |
*/ |
#ifndef BOOT_arm32_MAIN_H |
39,13 → 39,17 |
#define BOOT_arm32_MAIN_H |
/** Aligns to the nearest higher address. |
* |
* @param addr Address or number to be aligned. |
* @param align Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1)) |
/** Maximum number of tasks in the #bootinfo_t struct. */ |
#define TASKMAP_MAX_RECORDS 32 |
/** Size of buffer for storing task name in task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
/** Struct holding information about single loaded task. */ |
typedef struct { |
/** Address where the task was placed. */ |
52,8 → 56,6 |
void *addr; |
/** Size of the task's binary. */ |
unsigned int size; |
/** Task name. */ |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} task_t; |
72,3 → 74,4 |
/** @} |
*/ |
/branches/dd/boot/arch/arm32/loader/pack |
---|
0,0 → 1,139 |
#! /bin/sh |
# |
# Copyright (C) 2007 Michal Kebrt |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift 1 |
echo "OUTPUT_FORMAT(\"elf32-littlearm\") |
ENTRY(start) |
SECTIONS { |
.boot 0x0: AT (0) { |
*(BOOTSTRAP); |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.scommon); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.reginfo); |
. = 0x4000; |
*(PT); /* page table placed at 0x4000 */" > "$LINK" |
echo ' |
/** @addtogroup arm32boot |
* @{ |
*/ |
/** @file |
* @brief Components (kernel + tasks) related declarations. |
* |
* Generated by the <code>pack</code> script. This script packs all the |
* components (kernel + tasks) into one image (image.boot) and generates |
* a code that initializes an array of #component_t structs. |
*/ |
#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
/** Holds information about components packed to one image (kernel + tasks). */ |
typedef struct { |
/** Name. */ |
char *name; |
/** Start address. */ |
void *start; |
/** End address. */ |
void *end; |
/** Size (in bytes). */ |
unsigned int size; |
} component_t; |
/** @} |
*/ |
' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
. = ALIGN(4096); |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned int) ${MACRO}_END - (unsigned int) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf32-littlearm -B arm --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' } |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
/** Initializes array of components. */ |
static void init_components(component_t components[]) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/arm32/loader/main.c |
---|
32,16 → 32,13 |
*/ |
/** @file |
* @brief Bootstrap. |
*/ |
*/ |
#include "main.h" |
#include "main.h" |
#include "asm.h" |
#include "_components.h" |
#include <printf.h> |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
#include "mm.h" |
49,16 → 46,16 |
#define KERNEL_VIRTUAL_ADDRESS 0x80200000 |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
79,10 → 76,9 |
version_print(); |
component_t components[COMPONENTS]; |
bootinfo_t bootinfo; |
init_components(components); |
bootinfo_t bootinfo; |
printf("\nMemory statistics\n"); |
printf(" kernel entry point at %L\n", KERNEL_VIRTUAL_ADDRESS); |
printf(" %L: boot info structure\n", &bootinfo); |
104,8 → 100,6 |
if (i > 0) { |
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top; |
bootinfo.tasks[bootinfo.cnt].size = components[i].size; |
strncpy(bootinfo.tasks[bootinfo.cnt].name, |
components[i].name, BOOTINFO_TASK_NAME_BUFLEN); |
bootinfo.cnt++; |
} |
top += components[i].size; |
113,7 → 107,7 |
} |
printf("\nBooting the kernel...\n"); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo)); |
} |
/** @} |
/branches/dd/boot/arch/arm32/loader/asm.S |
---|
35,8 → 35,7 |
add r3, r1, #3 |
bic r3, r3, #3 |
cmp r1, r3 |
stmdb sp!, {r4, r5, lr} |
mov r5, r0 |
stmdb sp!, {r4, lr} |
beq 4f |
1: |
cmp r2, #0 |
49,8 → 48,8 |
cmp ip, r2 |
bne 2b |
3: |
mov r0, r5 |
ldmia sp!, {r4, r5, pc} |
mov r0, r1 |
ldmia sp!, {r4, pc} |
4: |
add r3, r0, #3 |
bic r3, r3, #3 |
/branches/dd/boot/arch/arm32/loader/boot.S |
---|
39,11 → 39,6 |
b bootstrap |
jump_to_kernel: |
# |
# TODO |
# Make sure that the I-cache, D-cache and memory are mutually coherent |
# before passing control to the copied code. |
# |
bx r0 |
53,3 → 48,5 |
# make place for PTL0 page table |
page_table: |
.skip PTL0_ENTRIES * PTL0_ENTRY_SIZE |
/branches/dd/boot/arch/arm32/Makefile.inc |
---|
28,15 → 28,15 |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot |
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot |
depend: |
-rm arch/$(BARCH)/loader/image.boot |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(BARCH)/loader/image.boot: |
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE) |
clean: |
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE) |
-rm -f $(BASE)/image.boot |
/branches/dd/boot/arch/ppc32/loader/_link.ld.in |
---|
File deleted |
/branches/dd/boot/arch/ppc32/loader/Makefile |
---|
27,19 → 27,13 |
# |
include ../../../../version |
-include ../../../../Makefile.config |
include ../../../Makefile.config |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
BFD_NAME = elf32-powerpc |
BFD_ARCH = powerpc:common |
TARGET = ppc-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/ppc/bin |
TOOLCHAIN_DIR = /usr/local/ppc/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
49,6 → 43,14 |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),icc_native) |
CC = icc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),gcc_cross) |
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc |
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as |
57,15 → 59,21 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -I../../../genarch -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 -pipe |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc -msoft-float -m32 |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
SOURCES = \ |
main.c \ |
ofwarch.c \ |
_components.c \ |
../../../genarch/ofw.c \ |
../../../generic/printf.c \ |
../../../generic/string.c \ |
asm.S \ |
boot.S |
72,31 → 80,17 |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
107,37 → 101,17 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 4096 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 4096 "unsigned int" $(COMPONENTS) ./initrd.img |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/boot/arch/ppc32/loader/asm.S |
---|
28,26 → 28,8 |
#include "asm.h" |
#include "regname.h" |
#include "debug.inc" |
.macro SMC_COHERENCY addr |
dcbst 0, \addr |
sync |
icbi 0, \addr |
sync |
isync |
.endm |
.macro FLUSH_DCACHE addr |
dcbst 0, \addr |
sync |
isync |
.endm |
.macro TLB_FLUSH reg |
tlbie \reg |
addi \reg, \reg, 0x1000 |
.endm |
.text |
.global halt |
158,6 → 140,9 |
real_mode: |
DEBUG_INIT |
DEBUG_real_mode |
# copy kernel to proper location |
# |
# r5 = trans (pa) |
178,13 → 163,14 |
mtctr r31 |
lwz r29, 0(r5) |
DEBUG_INIT |
DEBUG_copy_loop |
copy_loop: |
lwz r28, 0(r29) |
stw r28, 0(r30) |
SMC_COHERENCY r30 |
addi r29, r29, 4 |
addi r30, r30, 4 |
subi r6, r6, 4 |
194,11 → 180,15 |
bdnz copy_loop |
DEBUG_end_copy_loop |
addi r5, r5, 4 |
b page_copy |
copy_end: |
DEBUG_segments |
# initially fill segment registers |
li r31, 0 |
206,7 → 196,7 |
li r29, 8 |
mtctr r29 |
li r30, 0 # ASID 0 (VSIDs 0 .. 7) |
seg_fill_uspace: |
mtsrin r30, r31 |
230,6 → 220,8 |
# invalidate block address translation registers |
DEBUG_bat |
li r30, 0 |
mtspr ibat0u, r30 |
259,6 → 251,8 |
# create empty Page Hash Table |
# on top of memory, size 64 KB |
DEBUG_pht |
lwz r31, 0(r3) # r31 = memory size |
lis r30, 65536@h |
280,7 → 274,6 |
# write zeroes |
stw r29, 0(r31) |
FLUSH_DCACHE r31 |
addi r31, r31, 4 |
subi r30, r30, 4 |
289,6 → 282,8 |
beq clear_end |
bdnz pht_clear |
DEBUG_end_pht_clear |
clear_end: |
296,6 → 291,8 |
# create BAT identity mapping |
DEBUG_mapping |
lwz r31, 0(r3) # r31 = memory size |
lis r29, 0x0002 |
318,6 → 315,8 |
bdnz bat_mask |
DEBUG_bat_mask |
andi. r31, r31, 0x07ff # mask = mask & 0x07ff (BAT can map up to 256 MB) |
li r29, 2 |
337,90 → 336,16 |
mtspr dbat0l, r30 |
no_bat: |
#endif |
# flush TLB |
DEBUG_tlb |
li r31, 0 |
sync |
tlbia |
tlbsync |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
DEBUG_prepare |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
TLB_FLUSH r31 |
eieio |
tlbsync |
sync |
# start the kernel |
# |
# pc = KERNEL_START_ADDR |
448,6 → 373,8 |
sync |
isync |
DEBUG_rfi |
rfi |
.align PAGE_WIDTH |
/branches/dd/boot/arch/ppc32/loader/regname.h |
---|
208,13 → 208,11 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_dr (1 << 4) |
#define msr_ir (1 << 5) |
#define msr_pr (1 << 14) |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
#define msr_ee (1 << 15) |
/* HID0 bits */ |
#define hid0_sten (1 << 24) |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
/branches/dd/boot/arch/ppc32/loader/main.c |
---|
32,8 → 32,6 |
#include "_components.h" |
#include <ofw.h> |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
#define HEAP_GAP 1024000 |
74,16 → 72,16 |
} |
} |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
91,7 → 89,7 |
/** Print version information. */ |
static void version_print(void) |
{ |
printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n\n", release, revision, timestamp); |
printf("HelenOS PPC32 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp); |
} |
void bootstrap(void) |
98,10 → 96,10 |
{ |
version_print(); |
component_t components[COMPONENTS]; |
init_components(components); |
init_components(); |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
check_align(components[i].start, components[i].name); |
109,29 → 107,29 |
check_align(&trans, "translation table"); |
if (!ofw_memmap(&bootinfo.memmap)) { |
printf("Error: Unable to get memory map, halting.\n"); |
printf("Error: unable to get memory map, halting.\n"); |
halt(); |
} |
if (bootinfo.memmap.total == 0) { |
printf("Error: No memory detected, halting.\n"); |
printf("Error: no memory detected, halting.\n"); |
halt(); |
} |
if (!ofw_screen(&bootinfo.screen)) |
printf("Warning: Unable to get screen properties.\n"); |
if (!ofw_screen(&bootinfo.screen)) { |
printf("Error: unable to get screen properties, halting.\n"); |
halt(); |
} |
if (!ofw_macio(&bootinfo.macio)) |
printf("Warning: Unable to get macio properties.\n"); |
if (!ofw_keyboard(&bootinfo.keyboard)) { |
printf("Error: unable to get keyboard properties, halting.\n"); |
halt(); |
} |
printf("Device statistics\n"); |
printf("\nDevice statistics\n"); |
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline); |
printf(" keyboard at %L (size %d bytes)\n", bootinfo.keyboard.addr, bootinfo.keyboard.size); |
if (bootinfo.screen.addr) |
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline); |
if (bootinfo.macio.addr) |
printf(" macio at %L (size %d bytes)\n", bootinfo.macio.addr, bootinfo.macio.size); |
void *real_mode_pa = ofw_translate(&real_mode); |
void *trans_pa = ofw_translate(&trans); |
void *bootinfo_pa = ofw_translate(&bootinfo); |
167,9 → 165,6 |
if (j == 0) { |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH); |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size; |
strncpy(bootinfo.taskmap.tasks[bootinfo.taskmap.count].name, |
components[i].name, BOOTINFO_TASK_NAME_BUFLEN); |
bootinfo.taskmap.count++; |
} |
} |
181,8 → 176,6 |
fix_overlap(&trans, &trans_pa, "translation table", &top); |
fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top); |
ofw_setup_palette(); |
printf("\nBooting the kernel...\n"); |
jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa, (void *) bootinfo.screen.addr, bootinfo.screen.scanline); |
} |
/branches/dd/boot/arch/ppc32/loader/main.h |
---|
33,17 → 33,9 |
#define TASKMAP_MAX_RECORDS 32 |
/** Size of buffer for storing task name in task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
/** Struct holding information about single loaded task. */ |
typedef struct { |
/** Address where the task was placed. */ |
void *addr; |
/** Size of the task's binary. */ |
unsigned int size; |
/** Task name. */ |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} task_t; |
typedef struct { |
55,7 → 47,7 |
memmap_t memmap; |
taskmap_t taskmap; |
screen_t screen; |
macio_t macio; |
keyboard_t keyboard; |
} bootinfo_t; |
extern void start(void); |
/branches/dd/boot/arch/ppc32/loader/ofwarch.c |
---|
39,32 → 39,25 |
void write(const char *str, const int len) |
{ |
int i; |
for (i = 0; i < len; i++) { |
if (str[i] == '\n') |
ofw_write("\r", 1); |
ofw_write(&str[i], 1); |
} |
ofw_write(str, len); |
} |
int ofw_macio(macio_t *macio) |
int ofw_keyboard(keyboard_t *keyboard) |
{ |
char device_name[BUF_SIZE]; |
if (ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0) |
return false; |
phandle device = ofw_find_device(device_name); |
if (device == -1) |
return false; |
pci_reg_t pci_reg; |
if (ofw_get_property(device, "assigned-addresses", &pci_reg, sizeof(pci_reg)) <= 0) |
pci_reg_t macio; |
if (ofw_get_property(device, "assigned-addresses", &macio, sizeof(macio)) <= 0) |
return false; |
macio->addr = (void *) pci_reg.addr.addr_lo; |
macio->size = pci_reg.size_lo; |
keyboard->addr = (void *) macio.addr.addr_lo; |
keyboard->size = macio.size_lo; |
return true; |
} |
/branches/dd/boot/arch/ppc32/loader/debug.inc |
---|
0,0 → 1,11479 |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.macro DEBUG_INIT |
#ifdef CONFIG_DEBUG |
lis r11, 65535 |
ori r11, r11, 65535 |
lis r12, 0 |
ori r12, r12, 0 |
mr r10, r8 |
#endif |
.endm |
.macro DEBUG_real_mode |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
#endif |
.endm |
.macro DEBUG_copy_loop |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
#endif |
.endm |
.macro DEBUG_end_copy_loop |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r12, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r11, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
#endif |
.endm |
.macro DEBUG_segments |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
#endif |
.endm |
.macro DEBUG_bat |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_mapping |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
#endif |
.endm |
.macro DEBUG_tlb |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_prepare |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
#endif |
.endm |
.macro DEBUG_rfi |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_pht |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_end_pht_clear |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r12, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r11, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
#endif |
.endm |
.macro DEBUG_bat_mask |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
#endif |
.endm |
/branches/dd/boot/arch/ppc32/loader/pack |
---|
0,0 → 1,115 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift |
echo 'OUTPUT_FORMAT("elf32-powerpc") |
OUTPUT_ARCH(powerpc:common) |
ENTRY(start) |
SECTIONS { |
.boot 0x10000000: AT (0) { |
*(BOOTSTRAP); |
*(REALMODE); |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */' > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned int size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
. = ALIGN(4096); |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned int) ${MACRO}_END - (unsigned int) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf32-powerpc -B powerpc:common --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' } |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
component_t components[COMPONENTS]; |
static void init_components(void) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/ppc32/Makefile.inc |
---|
28,15 → 28,15 |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot |
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot |
depend: |
-rm arch/$(BARCH)/loader/image.boot |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(BARCH)/loader/image.boot: |
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
clean: generic_clean |
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) "DEFS=$(DEFS)" |
-rm -f $(BASE)/image.boot |
/branches/dd/boot/arch/ia32xen/grub/menu.lst |
---|
0,0 → 1,20 |
default 0 |
timeout 10 |
title=HelenOS/ia32xen |
root (cd) |
kernel /boot/xen.gz |
module /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/pci |
module /boot/fb |
module /boot/kbd |
module /boot/console |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/devmap |
module /boot/tetris |
module /boot/tester |
module /boot/klog |
/branches/dd/boot/arch/ia32xen/grub/menu.debug.lst |
---|
0,0 → 1,16 |
default 0 |
timeout 10 |
title=HelenOS/ia32xen |
root (cd) |
kernel /boot/xen.debug.gz noreboot console=com1,vga com1=auto,8n1,0x3f8 |
module /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/pci |
module /boot/fb |
module /boot/kbd |
module /boot/console |
module /boot/tetris |
module /boot/tester |
module /boot/klog |
/branches/dd/boot/arch/ia32xen/grub/xen.gz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/dd/boot/arch/ia32xen/grub/xen.debug.gz |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/dd/boot/arch/ia32xen/grub/stage2_eltorito |
---|
Cannot display: file marked as a binary type. |
svn:mime-type = application/octet-stream |
Property changes: |
Added: svn:mime-type |
+application/octet-stream |
\ No newline at end of property |
/branches/dd/boot/arch/ia32xen/grub/COPYING |
---|
0,0 → 1,340 |
GNU GENERAL PUBLIC LICENSE |
Version 2, June 1991 |
Copyright (C) 1989, 1991 Free Software Foundation, Inc. |
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Everyone is permitted to copy and distribute verbatim copies |
of this license document, but changing it is not allowed. |
Preamble |
The licenses for most software are designed to take away your |
freedom to share and change it. By contrast, the GNU General Public |
License is intended to guarantee your freedom to share and change free |
software--to make sure the software is free for all its users. This |
General Public License applies to most of the Free Software |
Foundation's software and to any other program whose authors commit to |
using it. (Some other Free Software Foundation software is covered by |
the GNU Library General Public License instead.) You can apply it to |
your programs, too. |
When we speak of free software, we are referring to freedom, not |
price. Our General Public Licenses are designed to make sure that you |
have the freedom to distribute copies of free software (and charge for |
this service if you wish), that you receive source code or can get it |
if you want it, that you can change the software or use pieces of it |
in new free programs; and that you know you can do these things. |
To protect your rights, we need to make restrictions that forbid |
anyone to deny you these rights or to ask you to surrender the rights. |
These restrictions translate to certain responsibilities for you if you |
distribute copies of the software, or if you modify it. |
For example, if you distribute copies of such a program, whether |
gratis or for a fee, you must give the recipients all the rights that |
you have. You must make sure that they, too, receive or can get the |
source code. And you must show them these terms so they know their |
rights. |
We protect your rights with two steps: (1) copyright the software, and |
(2) offer you this license which gives you legal permission to copy, |
distribute and/or modify the software. |
Also, for each author's protection and ours, we want to make certain |
that everyone understands that there is no warranty for this free |
software. If the software is modified by someone else and passed on, we |
want its recipients to know that what they have is not the original, so |
that any problems introduced by others will not reflect on the original |
authors' reputations. |
Finally, any free program is threatened constantly by software |
patents. We wish to avoid the danger that redistributors of a free |
program will individually obtain patent licenses, in effect making the |
program proprietary. To prevent this, we have made it clear that any |
patent must be licensed for everyone's free use or not licensed at all. |
The precise terms and conditions for copying, distribution and |
modification follow. |
GNU GENERAL PUBLIC LICENSE |
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION |
0. This License applies to any program or other work which contains |
a notice placed by the copyright holder saying it may be distributed |
under the terms of this General Public License. The "Program", below, |
refers to any such program or work, and a "work based on the Program" |
means either the Program or any derivative work under copyright law: |
that is to say, a work containing the Program or a portion of it, |
either verbatim or with modifications and/or translated into another |
language. (Hereinafter, translation is included without limitation in |
the term "modification".) Each licensee is addressed as "you". |
Activities other than copying, distribution and modification are not |
covered by this License; they are outside its scope. The act of |
running the Program is not restricted, and the output from the Program |
is covered only if its contents constitute a work based on the |
Program (independent of having been made by running the Program). |
Whether that is true depends on what the Program does. |
1. You may copy and distribute verbatim copies of the Program's |
source code as you receive it, in any medium, provided that you |
conspicuously and appropriately publish on each copy an appropriate |
copyright notice and disclaimer of warranty; keep intact all the |
notices that refer to this License and to the absence of any warranty; |
and give any other recipients of the Program a copy of this License |
along with the Program. |
You may charge a fee for the physical act of transferring a copy, and |
you may at your option offer warranty protection in exchange for a fee. |
2. You may modify your copy or copies of the Program or any portion |
of it, thus forming a work based on the Program, and copy and |
distribute such modifications or work under the terms of Section 1 |
above, provided that you also meet all of these conditions: |
a) You must cause the modified files to carry prominent notices |
stating that you changed the files and the date of any change. |
b) You must cause any work that you distribute or publish, that in |
whole or in part contains or is derived from the Program or any |
part thereof, to be licensed as a whole at no charge to all third |
parties under the terms of this License. |
c) If the modified program normally reads commands interactively |
when run, you must cause it, when started running for such |
interactive use in the most ordinary way, to print or display an |
announcement including an appropriate copyright notice and a |
notice that there is no warranty (or else, saying that you provide |
a warranty) and that users may redistribute the program under |
these conditions, and telling the user how to view a copy of this |
License. (Exception: if the Program itself is interactive but |
does not normally print such an announcement, your work based on |
the Program is not required to print an announcement.) |
These requirements apply to the modified work as a whole. If |
identifiable sections of that work are not derived from the Program, |
and can be reasonably considered independent and separate works in |
themselves, then this License, and its terms, do not apply to those |
sections when you distribute them as separate works. But when you |
distribute the same sections as part of a whole which is a work based |
on the Program, the distribution of the whole must be on the terms of |
this License, whose permissions for other licensees extend to the |
entire whole, and thus to each and every part regardless of who wrote it. |
Thus, it is not the intent of this section to claim rights or contest |
your rights to work written entirely by you; rather, the intent is to |
exercise the right to control the distribution of derivative or |
collective works based on the Program. |
In addition, mere aggregation of another work not based on the Program |
with the Program (or with a work based on the Program) on a volume of |
a storage or distribution medium does not bring the other work under |
the scope of this License. |
3. You may copy and distribute the Program (or a work based on it, |
under Section 2) in object code or executable form under the terms of |
Sections 1 and 2 above provided that you also do one of the following: |
a) Accompany it with the complete corresponding machine-readable |
source code, which must be distributed under the terms of Sections |
1 and 2 above on a medium customarily used for software interchange; or, |
b) Accompany it with a written offer, valid for at least three |
years, to give any third party, for a charge no more than your |
cost of physically performing source distribution, a complete |
machine-readable copy of the corresponding source code, to be |
distributed under the terms of Sections 1 and 2 above on a medium |
customarily used for software interchange; or, |
c) Accompany it with the information you received as to the offer |
to distribute corresponding source code. (This alternative is |
allowed only for noncommercial distribution and only if you |
received the program in object code or executable form with such |
an offer, in accord with Subsection b above.) |
The source code for a work means the preferred form of the work for |
making modifications to it. For an executable work, complete source |
code means all the source code for all modules it contains, plus any |
associated interface definition files, plus the scripts used to |
control compilation and installation of the executable. However, as a |
special exception, the source code distributed need not include |
anything that is normally distributed (in either source or binary |
form) with the major components (compiler, kernel, and so on) of the |
operating system on which the executable runs, unless that component |
itself accompanies the executable. |
If distribution of executable or object code is made by offering |
access to copy from a designated place, then offering equivalent |
access to copy the source code from the same place counts as |
distribution of the source code, even though third parties are not |
compelled to copy the source along with the object code. |
4. You may not copy, modify, sublicense, or distribute the Program |
except as expressly provided under this License. Any attempt |
otherwise to copy, modify, sublicense or distribute the Program is |
void, and will automatically terminate your rights under this License. |
However, parties who have received copies, or rights, from you under |
this License will not have their licenses terminated so long as such |
parties remain in full compliance. |
5. You are not required to accept this License, since you have not |
signed it. However, nothing else grants you permission to modify or |
distribute the Program or its derivative works. These actions are |
prohibited by law if you do not accept this License. Therefore, by |
modifying or distributing the Program (or any work based on the |
Program), you indicate your acceptance of this License to do so, and |
all its terms and conditions for copying, distributing or modifying |
the Program or works based on it. |
6. Each time you redistribute the Program (or any work based on the |
Program), the recipient automatically receives a license from the |
original licensor to copy, distribute or modify the Program subject to |
these terms and conditions. You may not impose any further |
restrictions on the recipients' exercise of the rights granted herein. |
You are not responsible for enforcing compliance by third parties to |
this License. |
7. If, as a consequence of a court judgment or allegation of patent |
infringement or for any other reason (not limited to patent issues), |
conditions are imposed on you (whether by court order, agreement or |
otherwise) that contradict the conditions of this License, they do not |
excuse you from the conditions of this License. If you cannot |
distribute so as to satisfy simultaneously your obligations under this |
License and any other pertinent obligations, then as a consequence you |
may not distribute the Program at all. For example, if a patent |
license would not permit royalty-free redistribution of the Program by |
all those who receive copies directly or indirectly through you, then |
the only way you could satisfy both it and this License would be to |
refrain entirely from distribution of the Program. |
If any portion of this section is held invalid or unenforceable under |
any particular circumstance, the balance of the section is intended to |
apply and the section as a whole is intended to apply in other |
circumstances. |
It is not the purpose of this section to induce you to infringe any |
patents or other property right claims or to contest validity of any |
such claims; this section has the sole purpose of protecting the |
integrity of the free software distribution system, which is |
implemented by public license practices. Many people have made |
generous contributions to the wide range of software distributed |
through that system in reliance on consistent application of that |
system; it is up to the author/donor to decide if he or she is willing |
to distribute software through any other system and a licensee cannot |
impose that choice. |
This section is intended to make thoroughly clear what is believed to |
be a consequence of the rest of this License. |
8. If the distribution and/or use of the Program is restricted in |
certain countries either by patents or by copyrighted interfaces, the |
original copyright holder who places the Program under this License |
may add an explicit geographical distribution limitation excluding |
those countries, so that distribution is permitted only in or among |
countries not thus excluded. In such case, this License incorporates |
the limitation as if written in the body of this License. |
9. The Free Software Foundation may publish revised and/or new versions |
of the General Public License from time to time. Such new versions will |
be similar in spirit to the present version, but may differ in detail to |
address new problems or concerns. |
Each version is given a distinguishing version number. If the Program |
specifies a version number of this License which applies to it and "any |
later version", you have the option of following the terms and conditions |
either of that version or of any later version published by the Free |
Software Foundation. If the Program does not specify a version number of |
this License, you may choose any version ever published by the Free Software |
Foundation. |
10. If you wish to incorporate parts of the Program into other free |
programs whose distribution conditions are different, write to the author |
to ask for permission. For software which is copyrighted by the Free |
Software Foundation, write to the Free Software Foundation; we sometimes |
make exceptions for this. Our decision will be guided by the two goals |
of preserving the free status of all derivatives of our free software and |
of promoting the sharing and reuse of software generally. |
NO WARRANTY |
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY |
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN |
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES |
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED |
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS |
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE |
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, |
REPAIR OR CORRECTION. |
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING |
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR |
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, |
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING |
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED |
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY |
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER |
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE |
POSSIBILITY OF SUCH DAMAGES. |
END OF TERMS AND CONDITIONS |
How to Apply These Terms to Your New Programs |
If you develop a new program, and you want it to be of the greatest |
possible use to the public, the best way to achieve this is to make it |
free software which everyone can redistribute and change under these terms. |
To do so, attach the following notices to the program. It is safest |
to attach them to the start of each source file to most effectively |
convey the exclusion of warranty; and each file should have at least |
the "copyright" line and a pointer to where the full notice is found. |
<one line to give the program's name and a brief idea of what it does.> |
Copyright (C) <year> <name of author> |
This program is free software; you can redistribute it and/or modify |
it under the terms of the GNU General Public License as published by |
the Free Software Foundation; either version 2 of the License, or |
(at your option) any later version. |
This program is distributed in the hope that it will be useful, |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
GNU General Public License for more details. |
You should have received a copy of the GNU General Public License |
along with this program; if not, write to the Free Software |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Also add information on how to contact you by electronic and paper mail. |
If the program is interactive, make it output a short notice like this |
when it starts in an interactive mode: |
Gnomovision version 69, Copyright (C) year name of author |
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. |
This is free software, and you are welcome to redistribute it |
under certain conditions; type `show c' for details. |
The hypothetical commands `show w' and `show c' should show the appropriate |
parts of the General Public License. Of course, the commands you use may |
be called something other than `show w' and `show c'; they could even be |
mouse-clicks or menu items--whatever suits your program. |
You should also get your employer (if you work as a programmer) or your |
school, if any, to sign a "copyright disclaimer" for the program, if |
necessary. Here is a sample; alter the names: |
Yoyodyne, Inc., hereby disclaims all copyright interest in the program |
`Gnomovision' (which makes passes at compilers) written by James Hacker. |
<signature of Ty Coon>, 1 April 1989 |
Ty Coon, President of Vice |
This General Public License does not permit incorporating your program into |
proprietary programs. If your program is a subroutine library, you may |
consider it more useful to permit linking proprietary applications with the |
library. If this is what you want to do, use the GNU Library General |
Public License instead of this License. |
/branches/dd/boot/arch/ia32xen/grub/README |
---|
0,0 → 1,5 |
For licensing terms of GRUB boot loader see the file COPYING contained |
in this directory. Full version of GRUB, including its source code, |
can be downloaded from GRUB's project page: |
http://www.gnu.org/software/grub/ |
/branches/dd/boot/arch/ia32xen/Makefile.inc |
---|
0,0 → 1,64 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
TASKS = \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/pci/pci \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/klog/klog |
build: $(BASE)/image.iso |
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/grub/menu.debug.lst arch/$(ARCH)/grub/xen.gz arch/$(ARCH)/grub/xen.debug.gz $(KERNELDIR)/kernel.bin $(TASKS) |
mkdir -p arch/$(ARCH)/iso/boot/grub |
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/ |
ifeq ($(CONFIG_DEBUG),y) |
cp arch/$(ARCH)/grub/menu.debug.lst arch/$(ARCH)/iso/boot/grub/menu.lst |
cp arch/$(ARCH)/grub/xen.debug.gz arch/$(ARCH)/iso/boot/ |
else |
cp arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/iso/boot/grub/ |
cp arch/$(ARCH)/grub/xen.gz arch/$(ARCH)/iso/boot/ |
endif |
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/ |
for task in $(TASKS) ; do \ |
cp $$task arch/$(ARCH)/iso/boot/ ; \ |
done |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/ |
clean: |
-rm -fr arch/$(ARCH)/iso |
-rm -f $(BASE)/image.iso |
/branches/dd/boot/arch/ppc64/loader/Makefile |
---|
0,0 → 1,120 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
include ../../../../version |
include ../../../Makefile.config |
## Toolchain configuration |
# |
TARGET = ppc64-linux-gnu |
TOOLCHAIN_DIR = /usr/local/ppc64/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),icc_native) |
CC = icc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),gcc_cross) |
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc |
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as |
LD = $(TOOLCHAIN_DIR)/$(TARGET)-ld |
OBJCOPY = $(TOOLCHAIN_DIR)/$(TARGET)-objcopy |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -I../../../genarch -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mcpu=powerpc64 -msoft-float -m64 |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
SOURCES = \ |
main.c \ |
ofwarch.c \ |
../../../genarch/ofw.c \ |
../../../generic/printf.c \ |
asm.S \ |
boot.S |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
COMPONENT_OBJECTS := $(addsuffix .o,$(basename $(notdir $(COMPONENTS)))) |
.PHONY: all clean depend |
all: image.boot |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(OBJCOPY) $(COMPONENTS) |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
%.o: %.c |
$(CC) $(DEFS) $(CFLAGS) -c $< -o $@ |
/branches/dd/boot/arch/ppc64/loader/ofwarch.h |
---|
0,0 → 1,35 |
/* |
* Copyright (c) 2006 Jakub Jermar |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef BOOT_ppc64_OFWARCH_H_ |
#define BOOT_ppc64_OFWARCH_H_ |
#define OFW_ADDRESS_CELLS 2 |
#define OFW_SIZE_CELLS 2 |
#endif |
/branches/dd/boot/arch/ppc64/loader/asm.S |
---|
0,0 → 1,301 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include "asm.h" |
#include "regname.h" |
#include "debug.inc" |
.text |
.global halt |
.global memcpy |
.global jump_to_kernel |
halt: |
b halt |
memcpy: |
srwi. r7, r5, 3 |
addi r6, r3, -4 |
addi r4, r4, -4 |
beq 2f |
andi. r0, r6, 3 |
mtctr r7 |
bne 5f |
1: |
lwz r7, 4(r4) |
lwzu r8, 8(r4) |
stw r7, 4(r6) |
stwu r8, 8(r6) |
bdnz 1b |
andi. r5, r5, 7 |
2: |
cmplwi 0, r5, 4 |
blt 3f |
lwzu r0, 4(r4) |
addi r5, r5, -4 |
stwu r0, 4(r6) |
3: |
cmpwi 0, r5, 0 |
beqlr |
mtctr r5 |
addi r4, r4, 3 |
addi r6, r6, 3 |
4: |
lbzu r0, 1(r4) |
stbu r0, 1(r6) |
bdnz 4b |
blr |
5: |
subfic r0, r0, 4 |
mtctr r0 |
6: |
lbz r7, 4(r4) |
addi r4, r4, 1 |
stb r7, 4(r6) |
addi r6, r6, 1 |
bdnz 6b |
subf r5, r0, r5 |
rlwinm. r7, r5, 32-3, 3, 31 |
beq 2b |
mtctr r7 |
b 1b |
jump_to_kernel: |
# r3 = bootinfo (pa) |
# r4 = bootinfo_size |
# r5 = trans (pa) |
# r6 = bytes to copy |
# r7 = real_mode (pa) |
# r8 = framebuffer (pa) |
# r9 = scanline |
# disable interrupts |
mfmsr r31 |
rlwinm r31, r31, 0, 17, 15 |
mtmsr r31 |
# set real_mode meeting point address |
mtspr srr0, r7 |
# jumps to real_mode |
mfmsr r31 |
lis r30, ~0@h |
ori r30, r30, ~(msr_ir | msr_dr)@l |
and r31, r31, r30 |
mtspr srr1, r31 |
sync |
isync |
rfid |
.section REALMODE, "ax" |
.align PAGE_WIDTH |
.global real_mode |
real_mode: |
DEBUG_INIT |
DEBUG_real_mode |
# copy kernel to proper location |
# |
# r5 = trans (pa) |
# r6 = bytes to copy |
# r8 = framebuffer (pa) |
# r9 = scanline |
li r31, PAGE_SIZE >> 2 |
li r30, 0 |
page_copy: |
cmpwi r6, 0 |
beq copy_end |
# copy page |
mtctr r31 |
lwz r29, 0(r5) |
DEBUG_INIT |
DEBUG_copy_loop |
copy_loop: |
lwz r28, 0(r29) |
stw r28, 0(r30) |
addi r29, r29, 4 |
addi r30, r30, 4 |
subi r6, r6, 4 |
cmpwi r6, 0 |
beq copy_end |
bdnz copy_loop |
DEBUG_end_copy_loop |
addi r5, r5, 4 |
b page_copy |
copy_end: |
DEBUG_segments |
# initially fill segment registers |
li r31, 0 |
li r29, 8 |
mtctr r29 |
li r30, 0 # ASID 0 (VSIDs 0 .. 7) |
seg_fill_uspace: |
mtsrin r30, r31 |
addi r30, r30, 1 |
addis r31, r31, 0x1000 # move to next SR |
bdnz seg_fill_uspace |
li r29, 8 |
mtctr r29 |
lis r30, 0x4000 # priviledged access only |
ori r30, r30, 8 # ASID 0 (VSIDs 8 .. 15) |
seg_fill_kernel: |
mtsrin r30, r31 |
addi r30, r30, 1 |
addis r31, r31, 0x1000 # move to next SR |
bdnz seg_fill_kernel |
# create empty Page Hash Table |
# on top of memory, size 64 KB |
DEBUG_pht |
lwz r31, 0(r3) # r31 = memory size |
lis r30, 65536@h |
ori r30, r30, 65536@l # r30 = 65536 |
subi r29, r30, 1 # r29 = 65535 |
sub r31, r31, r30 |
andc r31, r31, r29 # pht = ALIGN_DOWN(memory_size - 65536, 65536) |
mtsdr1 r31 |
li r29, 2 |
srw r30, r30, r29 # r30 = 16384 |
li r29, 0 |
pht_clear: |
# write zeroes |
stw r29, 0(r31) |
addi r31, r31, 4 |
subi r30, r30, 4 |
cmpwi r30, 0 |
beq clear_end |
bdnz pht_clear |
DEBUG_end_pht_clear |
clear_end: |
DEBUG_tlb |
tlbia |
tlbsync |
DEBUG_prepare |
# start the kernel |
# |
# pc = KERNEL_START_ADDR |
# r3 = bootinfo (pa) |
# sprg0 = KA2PA(KERNEL_START_ADDR) |
# sprg3 = physical memory size |
# sp = 0 (pa) |
lis r31, KERNEL_START_ADDR@ha |
addi r31, r31, KERNEL_START_ADDR@l |
mtspr srr0, r31 |
subis r31, r31, 0x8000 |
mtsprg0 r31 |
lwz r31, 0(r3) |
mtsprg3 r31 |
li sp, 0 |
mfmsr r31 |
ori r31, r31, (msr_ir | msr_dr)@l |
mtspr srr1, r31 |
sync |
isync |
DEBUG_rfi |
rfid |
.align PAGE_WIDTH |
.global trans |
trans: |
.space (TRANS_SIZE * TRANS_ITEM_SIZE) |
/branches/dd/boot/arch/ppc64/loader/boot.S |
---|
0,0 → 1,42 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
#include "regname.h" |
.section BOOTSTRAP, "ax" |
.global start |
start: |
lis r4, ofw_cif@ha |
addi r4, r4, ofw_cif@l |
stw r5, 0(r4) |
bl ofw_init |
b bootstrap |
/branches/dd/boot/arch/ppc64/loader/regname.h |
---|
0,0 → 1,204 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __ppc32_REGNAME_H__ |
#define __ppc32_REGNAME_H__ |
/* Condition Register Bit Fields */ |
#define cr0 0 |
#define cr1 1 |
#define cr2 2 |
#define cr3 3 |
#define cr4 4 |
#define cr5 5 |
#define cr6 6 |
#define cr7 7 |
/* General Purpose Registers (GPRs) */ |
#define r0 0 |
#define r1 1 |
#define r2 2 |
#define r3 3 |
#define r4 4 |
#define r5 5 |
#define r6 6 |
#define r7 7 |
#define r8 8 |
#define r9 9 |
#define r10 10 |
#define r11 11 |
#define r12 12 |
#define r13 13 |
#define r14 14 |
#define r15 15 |
#define r16 16 |
#define r17 17 |
#define r18 18 |
#define r19 19 |
#define r20 20 |
#define r21 21 |
#define r22 22 |
#define r23 23 |
#define r24 24 |
#define r25 25 |
#define r26 26 |
#define r27 27 |
#define r28 28 |
#define r29 29 |
#define r30 30 |
#define r31 31 |
/* GPR Aliases */ |
#define sp 1 |
/* Floating Point Registers (FPRs) */ |
#define fr0 0 |
#define fr1 1 |
#define fr2 2 |
#define fr3 3 |
#define fr4 4 |
#define fr5 5 |
#define fr6 6 |
#define fr7 7 |
#define fr8 8 |
#define fr9 9 |
#define fr10 10 |
#define fr11 11 |
#define fr12 12 |
#define fr13 13 |
#define fr14 14 |
#define fr15 15 |
#define fr16 16 |
#define fr17 17 |
#define fr18 18 |
#define fr19 19 |
#define fr20 20 |
#define fr21 21 |
#define fr22 22 |
#define fr23 23 |
#define fr24 24 |
#define fr25 25 |
#define fr26 26 |
#define fr27 27 |
#define fr28 28 |
#define fr29 29 |
#define fr30 30 |
#define fr31 31 |
#define vr0 0 |
#define vr1 1 |
#define vr2 2 |
#define vr3 3 |
#define vr4 4 |
#define vr5 5 |
#define vr6 6 |
#define vr7 7 |
#define vr8 8 |
#define vr9 9 |
#define vr10 10 |
#define vr11 11 |
#define vr12 12 |
#define vr13 13 |
#define vr14 14 |
#define vr15 15 |
#define vr16 16 |
#define vr17 17 |
#define vr18 18 |
#define vr19 19 |
#define vr20 20 |
#define vr21 21 |
#define vr22 22 |
#define vr23 23 |
#define vr24 24 |
#define vr25 25 |
#define vr26 26 |
#define vr27 27 |
#define vr28 28 |
#define vr29 29 |
#define vr30 30 |
#define vr31 31 |
#define evr0 0 |
#define evr1 1 |
#define evr2 2 |
#define evr3 3 |
#define evr4 4 |
#define evr5 5 |
#define evr6 6 |
#define evr7 7 |
#define evr8 8 |
#define evr9 9 |
#define evr10 10 |
#define evr11 11 |
#define evr12 12 |
#define evr13 13 |
#define evr14 14 |
#define evr15 15 |
#define evr16 16 |
#define evr17 17 |
#define evr18 18 |
#define evr19 19 |
#define evr20 20 |
#define evr21 21 |
#define evr22 22 |
#define evr23 23 |
#define evr24 24 |
#define evr25 25 |
#define evr26 26 |
#define evr27 27 |
#define evr28 28 |
#define evr29 29 |
#define evr30 30 |
#define evr31 31 |
/* Special Purpose Registers (SPRs) */ |
#define xer 1 |
#define lr 8 |
#define ctr 9 |
#define dec 22 |
#define sdr1 25 |
#define srr0 26 |
#define srr1 27 |
#define sprg0 272 |
#define sprg1 273 |
#define sprg2 274 |
#define sprg3 275 |
#define prv 287 |
#define hid0 1008 |
/* MSR bits */ |
#define msr_ir (1 << 4) |
#define msr_dr (1 << 5) |
/* HID0 bits */ |
#define hid0_ice (1 << 15) |
#define hid0_dce (1 << 14) |
#define hid0_icfi (1 << 11) |
#define hid0_dci (1 << 10) |
#endif |
/branches/dd/boot/arch/ppc64/loader/main.c |
---|
0,0 → 1,181 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "main.h" |
#include <printf.h> |
#include "asm.h" |
#include "_components.h" |
#include <ofw.h> |
#include <align.h> |
#define HEAP_GAP 1024000 |
bootinfo_t bootinfo; |
static void check_align(const void *addr, const char *desc) |
{ |
if ((unsigned long) addr % PAGE_SIZE != 0) { |
printf("Error: %s not on page boundary, halting.\n", desc); |
halt(); |
} |
} |
static void fix_overlap(void *va, void **pa, const char *desc, unsigned long *top) |
{ |
if ((unsigned long) *pa + PAGE_SIZE < *top) { |
printf("Warning: %s overlaps kernel physical area\n", desc); |
void *new_va = (void *) (ALIGN_UP((unsigned long) KERNEL_END + HEAP_GAP, PAGE_SIZE) + *top); |
void *new_pa = (void *) (HEAP_GAP + *top); |
*top += PAGE_SIZE; |
if (ofw_map(new_pa, new_va, PAGE_SIZE, 0) != 0) { |
printf("Error: Unable to map page aligned memory at %L (physical %L), halting.\n", new_va, new_pa); |
halt(); |
} |
if ((unsigned long) new_pa + PAGE_SIZE < KERNEL_SIZE) { |
printf("Error: %s cannot be relocated, halting.\n", desc); |
halt(); |
} |
printf("Relocating %L -> %L (physical %L -> %L)\n", va, new_va, *pa, new_pa); |
*pa = new_pa; |
memcpy(new_va, va, PAGE_SIZE); |
} |
} |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
/** Print version information. */ |
static void version_print(void) |
{ |
printf("HelenOS PPC64 Bootloader\nRelease %s%s%s\nCopyright (c) 2006 HelenOS project\n", release, revision, timestamp); |
} |
void bootstrap(void) |
{ |
version_print(); |
init_components(); |
unsigned int i; |
for (i = 0; i < COMPONENTS; i++) |
check_align(components[i].start, components[i].name); |
check_align(&real_mode, "bootstrap trampoline"); |
check_align(&trans, "translation table"); |
if (!ofw_memmap(&bootinfo.memmap)) { |
printf("Error: unable to get memory map, halting.\n"); |
halt(); |
} |
if (bootinfo.memmap.total == 0) { |
printf("Error: no memory detected, halting.\n"); |
halt(); |
} |
if (!ofw_screen(&bootinfo.screen)) { |
printf("Error: unable to get screen properties, halting.\n"); |
halt(); |
} |
if (!ofw_keyboard(&bootinfo.keyboard)) { |
printf("Error: unable to get keyboard properties, halting.\n"); |
halt(); |
} |
printf("\nDevice statistics\n"); |
printf(" screen at %L, resolution %dx%d, %d bpp (scanline %d bytes)\n", bootinfo.screen.addr, bootinfo.screen.width, bootinfo.screen.height, bootinfo.screen.bpp, bootinfo.screen.scanline); |
printf(" keyboard at %L (size %d bytes)\n", bootinfo.keyboard.addr, bootinfo.keyboard.size); |
void *real_mode_pa = ofw_translate(&real_mode); |
void *trans_pa = ofw_translate(&trans); |
void *bootinfo_pa = ofw_translate(&bootinfo); |
printf("\nMemory statistics (total %d MB)\n", bootinfo.memmap.total >> 20); |
printf(" %L: boot info structure (physical %L)\n", &bootinfo, bootinfo_pa); |
printf(" %L: bootstrap trampoline (physical %L)\n", &real_mode, real_mode_pa); |
printf(" %L: translation table (physical %L)\n", &trans, trans_pa); |
for (i = 0; i < COMPONENTS; i++) |
printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size); |
unsigned long top = 0; |
for (i = 0; i < COMPONENTS; i++) |
top += ALIGN_UP(components[i].size, PAGE_SIZE); |
unsigned long pages = ALIGN_UP(KERNEL_SIZE, PAGE_SIZE) >> PAGE_WIDTH; |
for (i = 0; i < pages; i++) { |
void *pa = ofw_translate(KERNEL_START + (i << PAGE_WIDTH)); |
fix_overlap(KERNEL_START + (i << PAGE_WIDTH), &pa, "kernel", &top); |
trans[i] = pa; |
} |
bootinfo.taskmap.count = 0; |
for (i = 1; i < COMPONENTS; i++) { |
unsigned long component_pages = ALIGN_UP(components[i].size, PAGE_SIZE) >> PAGE_WIDTH; |
unsigned long j; |
for (j = 0; j < component_pages; j++) { |
void *pa = ofw_translate(components[i].start + (j << PAGE_WIDTH)); |
fix_overlap(components[i].start + (j << PAGE_WIDTH), &pa, components[i].name, &top); |
trans[pages + j] = pa; |
if (j == 0) { |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].addr = (void *) (pages << PAGE_WIDTH); |
bootinfo.taskmap.tasks[bootinfo.taskmap.count].size = components[i].size; |
bootinfo.taskmap.count++; |
} |
} |
pages += component_pages; |
} |
fix_overlap(&real_mode, &real_mode_pa, "bootstrap trampoline", &top); |
fix_overlap(&trans, &trans_pa, "translation table", &top); |
fix_overlap(&bootinfo, &bootinfo_pa, "boot info", &top); |
printf("\nBooting the kernel...\n"); |
jump_to_kernel(bootinfo_pa, sizeof(bootinfo), trans_pa, pages << PAGE_WIDTH, real_mode_pa, (void *) bootinfo.screen.addr, bootinfo.screen.scanline); |
} |
/branches/dd/boot/arch/ppc64/loader/asm.h |
---|
0,0 → 1,52 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef BOOT_ppc64_ASM_H_ |
#define BOOT_ppc64_ASM_H_ |
#define PAGE_SIZE 4096 |
#define PAGE_WIDTH 12 |
#define TRANS_SIZE 1024 |
#define TRANS_ITEM_SIZE 8 |
#define KERNEL_START_ADDR 0x80008000 |
#ifndef __ASM__ |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
extern void *trans[TRANS_SIZE]; |
extern void halt(); |
extern void jump_to_kernel(void *bootinfo, unsigned long bootinfo_size, void *trans, unsigned long kernel_size, void *real_mode, void *fb, unsigned long scanline) __attribute__((noreturn)); |
extern void real_mode(); |
#endif |
#endif |
/branches/dd/boot/arch/ppc64/loader/main.h |
---|
0,0 → 1,58 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef BOOT_ppc64_MAIN_H_ |
#define BOOT_ppc64_MAIN_H_ |
#include "ofw.h" |
#define TASKMAP_MAX_RECORDS 32 |
typedef struct { |
void *addr; |
unsigned long size; |
} task_t; |
typedef struct { |
unsigned long count; |
task_t tasks[TASKMAP_MAX_RECORDS]; |
} taskmap_t; |
typedef struct { |
memmap_t memmap; |
taskmap_t taskmap; |
screen_t screen; |
keyboard_t keyboard; |
} bootinfo_t; |
extern void start(void); |
extern void bootstrap(void); |
extern memmap_t memmap; |
#endif |
/branches/dd/boot/arch/ppc64/loader/ofwarch.c |
---|
0,0 → 1,68 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <ofwarch.h> |
#include <ofw.h> |
#include <printf.h> |
typedef int (* ofw_entry_t)(ofw_args_t *args); |
int ofw(ofw_args_t *args) |
{ |
return ((ofw_entry_t) ofw_cif)(args); |
} |
void write(const char *str, const int len) |
{ |
ofw_write(str, len); |
} |
int ofw_keyboard(keyboard_t *keyboard) |
{ |
char device_name[BUF_SIZE]; |
if (ofw_get_property(ofw_aliases, "macio", device_name, sizeof(device_name)) <= 0) |
return false; |
phandle device = ofw_find_device(device_name); |
if (device == -1) |
return false; |
pci_reg_t macio; |
if (ofw_get_property(device, "assigned-addresses", &macio, sizeof(macio)) <= 0) |
return false; |
keyboard->addr = (void *) (((unsigned long) macio.addr.addr_lo) | (((unsigned long) macio.addr.addr_hi) << 32)); |
keyboard->size = macio.size_lo; |
return true; |
} |
int ofw_translate_failed(ofw_arg_t flag) |
{ |
return 0; |
} |
/branches/dd/boot/arch/ppc64/loader/types.h |
---|
0,0 → 1,44 |
/* |
* Copyright (c) 2006 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef BOOT_ppc64_TYPES_H_ |
#define BOOT_ppc64_TYPES_H_ |
#include <gentypes.h> |
typedef signed char int8_t; |
typedef unsigned char uint8_t; |
typedef unsigned short uint16_t; |
typedef unsigned int uint32_t; |
typedef unsigned long uint64_t; |
typedef uint64_t uintptr_t; |
typedef uint64_t unative_t; |
#endif |
/branches/dd/boot/arch/ppc64/loader/debug.inc |
---|
0,0 → 1,11479 |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
.macro DEBUG_INIT |
#ifdef CONFIG_DEBUG |
lis r11, 65535 |
ori r11, r11, 65535 |
lis r12, 0 |
ori r12, r12, 0 |
mr r10, r8 |
#endif |
.endm |
.macro DEBUG_real_mode |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
#endif |
.endm |
.macro DEBUG_copy_loop |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
#endif |
.endm |
.macro DEBUG_end_copy_loop |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r12, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r11, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
#endif |
.endm |
.macro DEBUG_segments |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
#endif |
.endm |
.macro DEBUG_bat |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_mapping |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
#endif |
.endm |
.macro DEBUG_tlb |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_prepare |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r12, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
#endif |
.endm |
.macro DEBUG_rfi |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_pht |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
#endif |
.endm |
.macro DEBUG_end_pht_clear |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r12, 396(r10) |
stw r11, 400(r10) |
stw r11, 404(r10) |
stw r11, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r11, 408(r10) |
stw r11, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r11, 260(r10) |
stw r11, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r11, 280(r10) |
stw r11, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r11, 324(r10) |
stw r11, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r11, 344(r10) |
stw r11, 348(r10) |
stw r12, 352(r10) |
stw r11, 356(r10) |
stw r11, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r11, 372(r10) |
stw r11, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r11, 264(r10) |
stw r11, 268(r10) |
stw r11, 272(r10) |
stw r11, 276(r10) |
stw r11, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r11, 300(r10) |
stw r11, 304(r10) |
stw r11, 308(r10) |
stw r11, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r11, 328(r10) |
stw r11, 332(r10) |
stw r11, 336(r10) |
stw r11, 340(r10) |
stw r11, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r11, 360(r10) |
stw r11, 364(r10) |
stw r11, 368(r10) |
stw r12, 372(r10) |
stw r11, 376(r10) |
stw r11, 380(r10) |
stw r12, 384(r10) |
stw r11, 388(r10) |
stw r11, 392(r10) |
stw r11, 396(r10) |
stw r11, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
stw r12, 256(r10) |
stw r12, 260(r10) |
stw r12, 264(r10) |
stw r12, 268(r10) |
stw r12, 272(r10) |
stw r12, 276(r10) |
stw r12, 280(r10) |
stw r12, 284(r10) |
stw r12, 288(r10) |
stw r12, 292(r10) |
stw r12, 296(r10) |
stw r12, 300(r10) |
stw r12, 304(r10) |
stw r12, 308(r10) |
stw r12, 312(r10) |
stw r12, 316(r10) |
stw r12, 320(r10) |
stw r12, 324(r10) |
stw r12, 328(r10) |
stw r12, 332(r10) |
stw r12, 336(r10) |
stw r12, 340(r10) |
stw r12, 344(r10) |
stw r12, 348(r10) |
stw r12, 352(r10) |
stw r12, 356(r10) |
stw r12, 360(r10) |
stw r12, 364(r10) |
stw r12, 368(r10) |
stw r12, 372(r10) |
stw r12, 376(r10) |
stw r12, 380(r10) |
stw r12, 384(r10) |
stw r12, 388(r10) |
stw r12, 392(r10) |
stw r12, 396(r10) |
stw r12, 400(r10) |
stw r12, 404(r10) |
stw r12, 408(r10) |
stw r12, 412(r10) |
#endif |
.endm |
.macro DEBUG_bat_mask |
#ifdef CONFIG_DEBUG |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r11, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r11, 68(r10) |
stw r11, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r12, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r11, 140(r10) |
stw r11, 144(r10) |
stw r11, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r11, 240(r10) |
stw r11, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r11, 244(r10) |
stw r11, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r11, 24(r10) |
stw r11, 28(r10) |
stw r12, 32(r10) |
stw r11, 36(r10) |
stw r11, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r11, 52(r10) |
stw r11, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r11, 76(r10) |
stw r11, 80(r10) |
stw r12, 84(r10) |
stw r11, 88(r10) |
stw r11, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r11, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r11, 164(r10) |
stw r11, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r11, 180(r10) |
stw r11, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r11, 196(r10) |
stw r11, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r11, 216(r10) |
stw r11, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r11, 8(r10) |
stw r11, 12(r10) |
stw r11, 16(r10) |
stw r11, 20(r10) |
stw r11, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r11, 40(r10) |
stw r11, 44(r10) |
stw r11, 48(r10) |
stw r12, 52(r10) |
stw r11, 56(r10) |
stw r11, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r11, 80(r10) |
stw r11, 84(r10) |
stw r11, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r11, 132(r10) |
stw r11, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r11, 152(r10) |
stw r11, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r11, 168(r10) |
stw r11, 172(r10) |
stw r11, 176(r10) |
stw r12, 180(r10) |
stw r11, 184(r10) |
stw r11, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r11, 200(r10) |
stw r11, 204(r10) |
stw r11, 208(r10) |
stw r11, 212(r10) |
stw r11, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r11, 228(r10) |
stw r11, 232(r10) |
stw r11, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r11, 248(r10) |
stw r11, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r11, 100(r10) |
stw r11, 104(r10) |
stw r11, 108(r10) |
stw r11, 112(r10) |
stw r11, 116(r10) |
stw r11, 120(r10) |
stw r11, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
add r10, r10, r9 |
stw r12, 0(r10) |
stw r12, 4(r10) |
stw r12, 8(r10) |
stw r12, 12(r10) |
stw r12, 16(r10) |
stw r12, 20(r10) |
stw r12, 24(r10) |
stw r12, 28(r10) |
stw r12, 32(r10) |
stw r12, 36(r10) |
stw r12, 40(r10) |
stw r12, 44(r10) |
stw r12, 48(r10) |
stw r12, 52(r10) |
stw r12, 56(r10) |
stw r12, 60(r10) |
stw r12, 64(r10) |
stw r12, 68(r10) |
stw r12, 72(r10) |
stw r12, 76(r10) |
stw r12, 80(r10) |
stw r12, 84(r10) |
stw r12, 88(r10) |
stw r12, 92(r10) |
stw r12, 96(r10) |
stw r12, 100(r10) |
stw r12, 104(r10) |
stw r12, 108(r10) |
stw r12, 112(r10) |
stw r12, 116(r10) |
stw r12, 120(r10) |
stw r12, 124(r10) |
stw r12, 128(r10) |
stw r12, 132(r10) |
stw r12, 136(r10) |
stw r12, 140(r10) |
stw r12, 144(r10) |
stw r12, 148(r10) |
stw r12, 152(r10) |
stw r12, 156(r10) |
stw r12, 160(r10) |
stw r12, 164(r10) |
stw r12, 168(r10) |
stw r12, 172(r10) |
stw r12, 176(r10) |
stw r12, 180(r10) |
stw r12, 184(r10) |
stw r12, 188(r10) |
stw r12, 192(r10) |
stw r12, 196(r10) |
stw r12, 200(r10) |
stw r12, 204(r10) |
stw r12, 208(r10) |
stw r12, 212(r10) |
stw r12, 216(r10) |
stw r12, 220(r10) |
stw r12, 224(r10) |
stw r12, 228(r10) |
stw r12, 232(r10) |
stw r12, 236(r10) |
stw r12, 240(r10) |
stw r12, 244(r10) |
stw r12, 248(r10) |
stw r12, 252(r10) |
#endif |
.endm |
/branches/dd/boot/arch/ppc64/loader/pack |
---|
0,0 → 1,124 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
OBJCOPY="$1" |
LINK="_link.ld" |
HEADER="_components.h" |
shift |
echo 'OUTPUT_FORMAT("elf64-powerpc") |
OUTPUT_ARCH(powerpc:common64) |
ENTRY(start) |
SECTIONS { |
.boot 0x0000000010000000: AT (0) { |
*(BOOTSTRAP); |
*(REALMODE); |
*(.text); |
*(.toc); |
*(.opd); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
. = ALIGN(4096); |
*(.kernel_image);' > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned long size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
. = ALIGN(4096); |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned long) ${MACRO}_END - (unsigned long) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf64-powerpc -B powerpc:common64 --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo '} |
/DISCARD/ : { |
*(*); |
} |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
component_t components[COMPONENTS]; |
static void init_components(void) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/ppc64/Makefile.inc |
---|
0,0 → 1,42 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot |
depend: |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
clean: generic_clean |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
-rm -f $(BASE)/image.boot |
/branches/dd/boot/arch/amd64/grub/menu.lst |
---|
2,14 → 2,18 |
timeout 10 |
title=HelenOS |
root (cd) |
kernel /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/devmap |
module /boot/rd |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/loader |
module /boot/initrd.img |
root (cd) |
kernel /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/pci |
module /boot/fb |
module /boot/kbd |
module /boot/console |
module /boot/tetris |
module /boot/tester |
module /boot/klog |
module /boot/tmpfs |
module /boot/fat |
module /boot/vfs |
module /boot/devmap |
/branches/dd/boot/arch/amd64/Makefile.inc |
---|
26,72 → 26,33 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
INIT_TASKS = \ |
TASKS = \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/pci/pci \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
$(USPACEDIR)/app/klog/klog |
build: $(BASE)/image.iso |
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) |
mkdir -p arch/$(BARCH)/iso/boot/grub |
cp arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/iso/boot/grub/ |
ifneq ($(RDFMT),tmpfs) |
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(BARCH)/iso/boot/grub/menu.lst |
endif |
ifneq ($(RDFMT),fat) |
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" >arch/$(BARCH)/iso/boot/grub/menu.lst |
endif |
cp $(KERNELDIR)/kernel.bin arch/$(BARCH)/iso/boot/ |
for task in $(INIT_TASKS) ; do \ |
cp $$task arch/$(BARCH)/iso/boot/ ; \ |
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(TASKS) |
mkdir -p arch/$(ARCH)/iso/boot/grub |
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/ |
cp arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/iso/boot/grub/ |
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/ |
for task in $(TASKS) ; do \ |
cp $$task arch/$(ARCH)/iso/boot/ ; \ |
done |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs |
endif |
$(BASE)/tools/mkhord.py 4096 arch/$(BARCH)/iso/boot/initrd.fs arch/$(BARCH)/iso/boot/initrd.img |
rm arch/$(BARCH)/iso/boot/initrd.fs |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(BARCH)/iso/ |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/ |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -fr arch/$(BARCH)/iso |
-rm -fr arch/$(ARCH)/iso |
-rm -f $(BASE)/image.iso |
/branches/dd/boot/arch/mips32/loader/_link.ld.in.ecoff |
---|
File deleted |
/branches/dd/boot/arch/mips32/loader/_link.ld.in.binary |
---|
File deleted |
/branches/dd/boot/arch/mips32/loader/Makefile |
---|
27,27 → 27,13 |
# |
include ../../../../version |
-include ../../../../Makefile.config |
include ../../../Makefile.config |
## Toolchain configuration |
# |
ifndef CROSS_PREFIX |
CROSS_PREFIX = /usr/local |
endif |
ifeq ($(IMAGE),binary) |
LD_IN = binary |
endif |
ifeq ($(IMAGE),ecoff) |
LD_IN = ecoff |
endif |
BFD_NAME = elf32-tradlittlemips |
BFD_ARCH = mips |
TARGET = mipsel-linux-gnu |
TOOLCHAIN_DIR = $(CROSS_PREFIX)/mipsel/bin |
TOOLCHAIN_DIR = /usr/local/mipsel/bin |
ifeq ($(COMPILER),gcc_native) |
CC = gcc |
57,6 → 43,14 |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),icc_native) |
CC = icc |
AS = as |
LD = ld |
OBJCOPY = objcopy |
OBJDUMP = objdump |
endif |
ifeq ($(COMPILER),gcc_cross) |
CC = $(TOOLCHAIN_DIR)/$(TARGET)-gcc |
AS = $(TOOLCHAIN_DIR)/$(TARGET)-as |
65,14 → 59,20 |
OBJDUMP = $(TOOLCHAIN_DIR)/$(TARGET)-objdump |
endif |
CFLAGS = -DRELEASE=$(RELEASE) -I. -I../../../generic -imacros ../../../../config.h -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 -pipe |
CFLAGS = -DRELEASE=\"$(RELEASE)\" -I. -I../../../generic -nostdinc -nostdlib -fno-builtin -Werror-implicit-function-declaration -Wmissing-prototypes -Werror -O3 -mno-abicalls -G 0 -fno-zero-initialized-in-bss -mhard-float -mips3 |
ifdef REVISION |
CFLAGS += "-DREVISION=\"$(REVISION)\"" |
endif |
ifdef TIMESTAMP |
CFLAGS += "-DTIMESTAMP=\"$(TIMESTAMP)\"" |
endif |
SOURCES = \ |
main.c \ |
msim.c \ |
_components.c \ |
../../../generic/printf.c \ |
../../../generic/string.c \ |
asm.S \ |
boot.S |
79,30 → 79,16 |
COMPONENTS = \ |
$(KERNELDIR)/kernel.bin \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
COMPONENTS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
COMPONENTS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/bdsh/bdsh \ |
$(USPACEDIR)/app/klog/klog |
OBJECTS := $(addsuffix .o,$(basename $(SOURCES))) |
114,41 → 100,18 |
-include Makefile.depend |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) -o $@ |
image.boot: depend _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) |
$(LD) -no-check-sections -N -T _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) -o $@ |
depend: |
-makedepend -f - -- $(DEFS) $(CFLAGS) -- $(SOURCES) > Makefile.depend 2> /dev/null |
-makedepend $(DEFS) $(CFLAGS) -f - $(SOURCES) > Makefile.depend 2> /dev/null |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -f _components.h _components.c _link.ld _link.ld.in $(COMPONENT_OBJECTS) initrd.o $(OBJECTS) initrd.img image.boot Makefile.depend |
-rm -f _components.h _link.ld $(COMPONENT_OBJECTS) $(OBJECTS) image.boot Makefile.depend |
_components.h _components.c _link.ld $(COMPONENT_OBJECTS) initrd.o: $(COMPONENTS) $(RD_SRVS) $(RD_APPS) _link.ld.in |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
../../../../tools/mktmpfs.py $(USPACEDIR)/dist/ initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
../../../../tools/mkfat.py $(USPACEDIR)/dist/ initrd.fs |
endif |
../../../../tools/mkhord.py 16384 initrd.fs initrd.img |
rm initrd.fs |
../../../tools/pack.py $(OBJCOPY) $(BFD_NAME) $(BFD_ARCH) 16384 "unsigned int" $(COMPONENTS) ./initrd.img |
_components.h _link.ld $(COMPONENT_OBJECTS): $(COMPONENTS) |
./pack $(IMAGE) $(OBJCOPY) $(COMPONENTS) |
_link.ld.in: _link.ld.in.$(LD_IN) |
cp $< $@ |
%.o: %.S |
$(CC) $(DEFS) $(CFLAGS) -D__ASM__ -c $< -o $@ |
/branches/dd/boot/arch/mips32/loader/asm.h |
---|
29,11 → 29,11 |
#ifndef BOOT_mips32_ASM_H_ |
#define BOOT_mips32_ASM_H_ |
#define PAGE_SIZE 16384 |
#define PAGE_WIDTH 14 |
#define PAGE_SIZE 16384 |
#define PAGE_WIDTH 14 |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
#define memcpy(dst, src, cnt) __builtin_memcpy((dst), (src), (cnt)) |
void jump_to_kernel(void *entry, void *bootinfo) __attribute__((noreturn)); |
void jump_to_kernel(void *entry, void *bootinfo, unsigned int bootinfo_size) __attribute__((noreturn)); |
#endif |
/branches/dd/boot/arch/mips32/loader/main.h |
---|
29,30 → 29,21 |
#ifndef BOOT_mips32_MAIN_H_ |
#define BOOT_mips32_MAIN_H_ |
#define CPUMAP 0x80001000 |
#define INITIAL_STACK 0x80002000 |
#define MSIM_DORDER_ADDRESS 0xb0000004 |
/** Align to the nearest higher address. |
* |
* @param addr Address or size to be aligned. |
* @param align Size of alignment, must be power of 2. |
*/ |
#define ALIGN_UP(addr, align) (((addr) + ((align) - 1)) & ~((align) - 1)) |
#define TASKMAP_MAX_RECORDS 32 |
#define CPUMAP_MAX_RECORDS 32 |
#define TASKMAP_MAX_RECORDS 32 |
#ifndef __ASM__ |
/** Size of buffer for storing task name in task_t. */ |
#define BOOTINFO_TASK_NAME_BUFLEN 32 |
/** Struct holding information about single loaded task. */ |
typedef struct { |
/** Address where the task was placed. */ |
void *addr; |
/** Size of the task's binary. */ |
unsigned int size; |
/** Task name. */ |
char name[BOOTINFO_TASK_NAME_BUFLEN]; |
} task_t; |
typedef struct { |
unsigned int cpumap; |
unsigned int cnt; |
task_t tasks[TASKMAP_MAX_RECORDS]; |
} bootinfo_t; |
61,5 → 52,3 |
extern void bootstrap(void); |
#endif |
#endif |
/branches/dd/boot/arch/mips32/loader/asm.S |
---|
48,7 → 48,6 |
and $v0,$v0,$v1 |
beq $a1,$v0,3f |
move $t0,$a0 |
move $t2,$a0 # save dst |
0: |
beq $a2,$zero,2f |
64,7 → 63,7 |
2: |
jr $ra |
move $v0,$t2 |
move $v0,$a1 |
3: |
addiu $v0,$a0,3 |
104,13 → 103,9 |
sb $a0,0($v1) |
jr $ra |
move $v0,$t2 |
move $v0,$a1 |
jump_to_kernel: |
# |
# TODO |
# Make sure that the I-cache, D-cache and memory are mutually coherent |
# before passing control to the copied code. |
# |
# .word 0x39 |
j $a0 |
nop |
/branches/dd/boot/arch/mips32/loader/boot.S |
---|
27,8 → 27,9 |
# |
#include "regname.h" |
#include "main.h" |
#define INITIAL_STACK 0x80040000 |
.set noat |
.set noreorder |
.set nomacro |
37,82 → 38,8 |
.global start |
start: |
lui $sp, INITIAL_STACK >> 16 |
ori $sp, $sp, INITIAL_STACK & 0xffff |
/* Setup CPU map (on msim this code |
is executed in parallel on all CPUs, |
but it not an issue) */ |
la $a0, CPUMAP |
sw $zero, 0($a0) |
sw $zero, 4($a0) |
sw $zero, 8($a0) |
sw $zero, 12($a0) |
sw $zero, 16($a0) |
sw $zero, 20($a0) |
sw $zero, 24($a0) |
sw $zero, 28($a0) |
sw $zero, 32($a0) |
sw $zero, 36($a0) |
sw $zero, 40($a0) |
sw $zero, 44($a0) |
sw $zero, 48($a0) |
sw $zero, 52($a0) |
sw $zero, 56($a0) |
sw $zero, 60($a0) |
sw $zero, 64($a0) |
sw $zero, 68($a0) |
sw $zero, 72($a0) |
sw $zero, 76($a0) |
sw $zero, 80($a0) |
sw $zero, 84($a0) |
sw $zero, 88($a0) |
sw $zero, 92($a0) |
sw $zero, 96($a0) |
sw $zero, 100($a0) |
sw $zero, 104($a0) |
sw $zero, 108($a0) |
sw $zero, 112($a0) |
sw $zero, 116($a0) |
sw $zero, 120($a0) |
sw $zero, 124($a0) |
lui $a1, 1 |
#ifdef MACHINE_msim |
/* Read dorder value */ |
la $k0, MSIM_DORDER_ADDRESS |
lw $k1, ($k0) |
/* If we are not running on BSP |
then end in an infinite loop */ |
beq $k1, $zero, bsp |
j bootstrap |
nop |
/* Record CPU presence */ |
sll $a2, $k1, 2 |
addu $a2, $a2, $a0 |
sw $a1, ($a2) |
loop: |
j loop |
nop |
#endif |
bsp: |
/* Record CPU presence */ |
sw $a1, ($a0) |
/* Setup initial stack */ |
la $sp, INITIAL_STACK |
j bootstrap |
nop |
/branches/dd/boot/arch/mips32/loader/main.c |
---|
28,9 → 28,6 |
#include "main.h" |
#include <printf.h> |
#include <align.h> |
#include <macros.h> |
#include <string.h> |
#include "msim.h" |
#include "asm.h" |
#include "_components.h" |
37,16 → 34,16 |
#define KERNEL_VIRTUAL_ADDRESS 0x80100000 |
char *release = STRING(RELEASE); |
char *release = RELEASE; |
#ifdef REVISION |
char *revision = ", revision " STRING(REVISION); |
char *revision = ", revision " REVISION; |
#else |
char *revision = ""; |
#endif |
#ifdef TIMESTAMP |
char *timestamp = "\nBuilt on " STRING(TIMESTAMP); |
char *timestamp = "\nBuilt on " TIMESTAMP; |
#else |
char *timestamp = ""; |
#endif |
62,10 → 59,9 |
version_print(); |
component_t components[COMPONENTS]; |
bootinfo_t bootinfo; |
init_components(components); |
bootinfo_t bootinfo; |
printf("\nMemory statistics\n"); |
printf(" kernel entry point at %L\n", KERNEL_VIRTUAL_ADDRESS); |
printf(" %L: boot info structure\n", &bootinfo); |
75,10 → 71,9 |
printf(" %L: %s image (size %d bytes)\n", components[i].start, components[i].name, components[i].size); |
printf("\nCopying components\n"); |
unsigned int top = 0; |
bootinfo.cnt = 0; |
for (i = 0; i < min(COMPONENTS, TASKMAP_MAX_RECORDS); i++) { |
for (i = 0; i < COMPONENTS; i++) { |
printf(" %s...", components[i].name); |
top = ALIGN_UP(top, PAGE_SIZE); |
memcpy(((void *) KERNEL_VIRTUAL_ADDRESS) + top, components[i].start, components[i].size); |
85,8 → 80,6 |
if (i > 0) { |
bootinfo.tasks[bootinfo.cnt].addr = ((void *) KERNEL_VIRTUAL_ADDRESS) + top; |
bootinfo.tasks[bootinfo.cnt].size = components[i].size; |
strncpy(bootinfo.tasks[bootinfo.cnt].name, |
components[i].name, BOOTINFO_TASK_NAME_BUFLEN); |
bootinfo.cnt++; |
} |
top += components[i].size; |
93,13 → 86,6 |
printf("done.\n"); |
} |
unsigned int *cpumap = (unsigned int *) CPUMAP; |
bootinfo.cpumap = 0; |
for (i = 0; i < CPUMAP_MAX_RECORDS; i++) { |
if (cpumap[i] != 0) |
bootinfo.cpumap |= (1 << i); |
} |
printf("\nBooting the kernel...\n"); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo); |
jump_to_kernel((void *) KERNEL_VIRTUAL_ADDRESS, &bootinfo, sizeof(bootinfo)); |
} |
/branches/dd/boot/arch/mips32/loader/pack |
---|
0,0 → 1,126 |
#! /bin/sh |
# |
# Copyright (C) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
[ "$#" -lt 1 ] && exit 1 |
case "$1" in |
"binary") |
BFD="binary" |
;; |
"ecoff") |
BFD="ecoff-littlemips" |
;; |
*) |
echo "Undefined image format" >&1 |
exit 1 |
;; |
esac |
OBJCOPY="$2" |
LINK="_link.ld" |
HEADER="_components.h" |
shift 2 |
echo "OUTPUT_FORMAT(\"${BFD}\") |
ENTRY(start) |
SECTIONS { |
.boot 0xbfc00000: AT (0) { |
*(BOOTSTRAP); |
*(.text); |
*(.rodata); |
*(.rodata.*); |
*(.data); /* initialized data */ |
*(.sdata); |
*(.sdata2); |
*(.sbss); |
*(.scommon); |
*(.bss); /* uninitialized static variables */ |
*(COMMON); /* global variables */ |
*(.reginfo);" > "$LINK" |
echo '#ifndef ___COMPONENTS_H__ |
#define ___COMPONENTS_H__ |
typedef struct { |
char *name; |
void *start; |
void *end; |
unsigned int size; |
} component_t;' > "$HEADER" |
COUNT="0" |
DATA="" |
for TASK in "$@" ; do |
BASENAME="`basename "$TASK" | sed 's/^\(.*\)\.[^.]*$/\1/'`" |
OBJECT="${BASENAME}.o" |
SYMBOL="`echo "_binary_$TASK" | tr "./" "__"`" |
MACRO="`echo "$BASENAME" | tr [:lower:] [:upper:]`" |
echo "$TASK -> $OBJECT" |
echo " |
. = ALIGN(4096); |
*(.${BASENAME}_image);" >> "$LINK" |
echo " |
extern int ${SYMBOL}_start; |
extern int ${SYMBOL}_end; |
#define ${MACRO}_START ((void *) &${SYMBOL}_start) |
#define ${MACRO}_END ((void *) &${SYMBOL}_end) |
#define ${MACRO}_SIZE ((unsigned int) ${MACRO}_END - (unsigned int) ${MACRO}_START)" >> "$HEADER" |
"$OBJCOPY" -I binary -O elf32-tradlittlemips -B mips --rename-section ".data=.${BASENAME}_image" "$TASK" "$OBJECT" |
DATA="${DATA} |
components[$COUNT].name = \"${BASENAME}\"; |
components[$COUNT].start = ${MACRO}_START; |
components[$COUNT].end = ${MACRO}_END; |
components[$COUNT].size = ${MACRO}_SIZE;"; |
COUNT="`expr "$COUNT" + 1`" |
done |
echo ' } |
}' >> "$LINK" |
echo " |
#define COMPONENTS $COUNT |
static void init_components(component_t components[]) |
{ |
$DATA |
} |
#endif |
" >> "$HEADER" |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/boot/arch/mips32/Makefile.inc |
---|
28,15 → 28,15 |
build: $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(BARCH)/loader/image.boot |
cp arch/$(BARCH)/loader/image.boot $(BASE)/image.boot |
$(BASE)/image.boot: depend arch/$(ARCH)/loader/image.boot |
cp arch/$(ARCH)/loader/image.boot $(BASE)/image.boot |
depend: |
-rm arch/$(BARCH)/loader/image.boot |
-rm arch/$(ARCH)/loader/image.boot |
arch/$(BARCH)/loader/image.boot: |
make -C arch/$(BARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
arch/$(ARCH)/loader/image.boot: |
make -C arch/$(ARCH)/loader COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE) |
clean: |
make -C arch/$(BARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) |
make -C arch/$(ARCH)/loader clean COMPILER=$(COMPILER) KERNELDIR=../../../$(KERNELDIR) USPACEDIR=../../../$(USPACEDIR) IMAGE=$(IMAGE) |
-rm -f $(BASE)/image.boot |
/branches/dd/boot/arch/ia32/grub/menu.lst |
---|
2,14 → 2,18 |
timeout 10 |
title=HelenOS |
root (cd) |
kernel /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/devmap |
module /boot/rd |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/loader |
module /boot/initrd.img |
root (cd) |
kernel /boot/kernel.bin |
module /boot/ns |
module /boot/init |
module /boot/pci |
module /boot/fb |
module /boot/kbd |
module /boot/console |
module /boot/vfs |
module /boot/tmpfs |
module /boot/fat |
module /boot/devmap |
module /boot/tetris |
module /boot/tester |
module /boot/klog |
/branches/dd/boot/arch/ia32/Makefile.inc |
---|
26,71 → 26,33 |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
INIT_TASKS = \ |
TASKS = \ |
$(USPACEDIR)/srv/ns/ns \ |
$(USPACEDIR)/srv/loader/loader \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/srv/rd/rd \ |
$(USPACEDIR)/srv/vfs/vfs |
ifeq ($(RDFMT),tmpfs) |
INIT_TASKS += $(USPACEDIR)/srv/fs/tmpfs/tmpfs |
endif |
ifeq ($(RDFMT),fat) |
INIT_TASKS += $(USPACEDIR)/srv/fs/fat/fat |
endif |
RD_SRVS = \ |
$(USPACEDIR)/srv/pci/pci \ |
$(USPACEDIR)/srv/fb/fb \ |
$(USPACEDIR)/srv/kbd/kbd \ |
$(USPACEDIR)/srv/console/console \ |
$(USPACEDIR)/srv/fs/fat/fat |
RD_APPS = \ |
$(USPACEDIR)/srv/vfs/vfs \ |
$(USPACEDIR)/srv/fs/tmpfs/tmpfs \ |
$(USPACEDIR)/srv/fs/fat/fat \ |
$(USPACEDIR)/srv/devmap/devmap \ |
$(USPACEDIR)/app/init/init \ |
$(USPACEDIR)/app/tetris/tetris \ |
$(USPACEDIR)/app/tester/tester \ |
$(USPACEDIR)/app/trace/trace \ |
$(USPACEDIR)/app/klog/klog \ |
$(USPACEDIR)/app/bdsh/bdsh |
$(USPACEDIR)/app/klog/klog |
build: $(BASE)/image.iso |
$(BASE)/image.iso: arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(INIT_TASKS) $(RD_SRVS) $(RD_APPS) |
mkdir -p arch/$(BARCH)/iso/boot/grub |
cp arch/$(BARCH)/grub/stage2_eltorito arch/$(BARCH)/iso/boot/grub/ |
ifneq ($(RDFMT),tmpfs) |
cat arch/$(BARCH)/grub/menu.lst | grep -v "tmpfs" >arch/$(BARCH)/iso/boot/grub/menu.lst |
endif |
ifneq ($(RDFMT),fat) |
cat arch/$(BARCH)/grub/menu.lst | grep -v "fat" >arch/$(BARCH)/iso/boot/grub/menu.lst |
endif |
cp $(KERNELDIR)/kernel.bin arch/$(BARCH)/iso/boot/ |
for task in $(INIT_TASKS) ; do \ |
cp $$task arch/$(BARCH)/iso/boot/ ; \ |
$(BASE)/image.iso: arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/grub/menu.lst $(KERNELDIR)/kernel.bin $(TASKS) |
mkdir -p arch/$(ARCH)/iso/boot/grub |
cp arch/$(ARCH)/grub/stage2_eltorito arch/$(ARCH)/iso/boot/grub/ |
cp arch/$(ARCH)/grub/menu.lst arch/$(ARCH)/iso/boot/grub/ |
cp $(KERNELDIR)/kernel.bin arch/$(ARCH)/iso/boot/ |
for task in $(TASKS) ; do \ |
cp $$task arch/$(ARCH)/iso/boot/ ; \ |
done |
for file in $(RD_SRVS) ; do \ |
cp $$file $(USPACEDIR)/dist/srv/ ; \ |
done |
for file in $(RD_APPS) ; do \ |
cp $$file $(USPACEDIR)/dist/app/ ; \ |
done |
ifeq ($(RDFMT),tmpfs) |
$(BASE)/tools/mktmpfs.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs |
endif |
ifeq ($(RDFMT),fat) |
$(BASE)/tools/mkfat.py $(USPACEDIR)/dist/ arch/$(BARCH)/iso/boot/initrd.fs |
endif |
$(BASE)/tools/mkhord.py 4096 arch/$(BARCH)/iso/boot/initrd.fs arch/$(BARCH)/iso/boot/initrd.img |
rm arch/$(BARCH)/iso/boot/initrd.fs |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(BARCH)/iso/ |
mkisofs -J -r -b boot/grub/stage2_eltorito -no-emul-boot -boot-load-size 4 -boot-info-table -o $(BASE)/image.iso arch/$(ARCH)/iso/ |
clean: |
-for file in $(RD_SRVS) ; do \ |
rm -f $(USPACEDIR)/dist/srv/`basename $$file` ; \ |
done |
-for file in $(RD_APPS) ; do \ |
rm -f $(USPACEDIR)/dist/app/`basename $$file` ; \ |
done |
-rm -fr arch/$(BARCH)/iso |
-rm -fr arch/$(ARCH)/iso |
-rm -f $(BASE)/image.iso |
/branches/dd/boot/genarch/ofw.h |
---|
74,7 → 74,7 |
typedef struct { |
void *addr; |
uint32_t size; |
} macio_t; |
} keyboard_t; |
typedef struct { |
uint32_t info; |
122,8 → 122,7 |
extern int ofw_map(const void *phys, const void *virt, const int size, const int mode); |
extern int ofw_memmap(memmap_t *map); |
extern int ofw_screen(screen_t *screen); |
extern int ofw_macio(macio_t *macio); |
extern int ofw_setup_palette(void); |
extern int ofw_keyboard(keyboard_t *keyboard); |
extern void ofw_quiesce(void); |
#endif |
/branches/dd/boot/genarch/balloc.h |
---|
31,7 → 31,7 |
#include <types.h> |
#define BALLOC_MAX_SIZE (128 * 1024) |
#define BALLOC_MAX_SIZE (1024 * 1024) |
typedef struct { |
uintptr_t base; |
/branches/dd/boot/genarch/ofw.c |
---|
25,7 → 25,7 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <ofw.h> |
#include <ofwarch.h> |
#include <printf.h> |
48,8 → 48,7 |
if (ofw_chosen == -1) |
halt(); |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, |
sizeof(ofw_stdout)) <= 0) |
if (ofw_get_property(ofw_chosen, "stdout", &ofw_stdout, sizeof(ofw_stdout)) <= 0) |
ofw_stdout = 0; |
ofw_root = ofw_find_device("/"); |
58,13 → 57,11 |
halt(); |
} |
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, |
sizeof(ofw_mmu)) <= 0) { |
if (ofw_get_property(ofw_chosen, "mmu", &ofw_mmu, sizeof(ofw_mmu)) <= 0) { |
puts("\r\nError: Unable to get mmu property, halted.\r\n"); |
halt(); |
} |
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, |
sizeof(ofw_memory_prop)) <= 0) { |
if (ofw_get_property(ofw_chosen, "memory", &ofw_memory_prop, sizeof(ofw_memory_prop)) <= 0) { |
puts("\r\nError: Unable to get memory property, halted.\r\n"); |
halt(); |
} |
84,18 → 81,14 |
/** Perform a call to OpenFirmware client interface. |
* |
* @param service String identifying the service requested. |
* @param nargs Number of input arguments. |
* @param nret Number of output arguments. This includes the return |
* value. |
* @param rets Buffer for output arguments or NULL. The buffer must |
* accommodate nret - 1 items. |
* @param service String identifying the service requested. |
* @param nargs Number of input arguments. |
* @param nret Number of output arguments. This includes the return value. |
* @param rets Buffer for output arguments or NULL. The buffer must accommodate nret - 1 items. |
* |
* @return Return value returned by the client interface. |
* @return Return value returned by the client interface. |
*/ |
unsigned long |
ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, |
...) |
unsigned long ofw_call(const char *service, const int nargs, const int nret, ofw_arg_t *rets, ...) |
{ |
va_list list; |
ofw_args_t args; |
126,9 → 119,7 |
return ofw_call("finddevice", 1, 1, NULL, name); |
} |
int |
ofw_get_property(const phandle device, const char *name, void *buf, |
const int buflen) |
int ofw_get_property(const phandle device, const char *name, void *buf, const int buflen) |
{ |
return ofw_call("getprop", 4, 1, NULL, device, name, buf, buflen); |
} |
153,8 → 144,7 |
unsigned int ret = 1; |
if (ofw_get_property(device, "#address-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#address-cells", &ret, |
sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#address-cells", &ret, sizeof(ret)) <= 0) |
ret = OFW_ADDRESS_CELLS; |
return ret; |
166,8 → 156,7 |
unsigned int ret; |
if (ofw_get_property(device, "#size-cells", &ret, sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#size-cells", &ret, |
sizeof(ret)) <= 0) |
if (ofw_get_property(ofw_root, "#size-cells", &ret, sizeof(ret)) <= 0) |
ret = OFW_SIZE_CELLS; |
return ret; |
203,8 → 192,7 |
ofw_arg_t result[4]; |
int shift; |
if (ofw_call("call-method", 4, 5, result, "translate", ofw_mmu, |
virt, 0) != 0) { |
if (ofw_call("call-method", 3, 5, result, "translate", ofw_mmu, virt) != 0) { |
puts("Error: MMU method translate() failed, halting.\n"); |
halt(); |
} |
224,8 → 212,7 |
{ |
ofw_arg_t retaddr; |
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, |
virt) != 0) { |
if (ofw_call("call-method", 5, 2, &retaddr, "claim", ofw_mmu, 0, len, virt) != 0) { |
puts("Error: MMU method claim() failed, halting.\n"); |
halt(); |
} |
282,8 → 269,8 |
phys_lo = (uintptr_t) phys; |
} |
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, |
virt, phys_hi, phys_lo); |
return ofw_call("call-method", 7, 1, NULL, "map", ofw_mmu, mode, size, virt, |
phys_hi, phys_lo); |
} |
/** Save OpenFirmware physical memory map. |
294,12 → 281,10 |
*/ |
int ofw_memmap(memmap_t *map) |
{ |
unsigned int ac = ofw_get_address_cells(ofw_memory) / |
(sizeof(uintptr_t) / sizeof(uint32_t)); |
unsigned int sc = ofw_get_size_cells(ofw_memory) / |
(sizeof(uintptr_t) / sizeof(uint32_t)); |
unsigned int ac = ofw_get_address_cells(ofw_memory); |
unsigned int sc = ofw_get_size_cells(ofw_memory); |
uintptr_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)]; |
uint32_t buf[((ac + sc) * MEMMAP_MAX_RECORDS)]; |
int ret = ofw_get_property(ofw_memory, "reg", buf, sizeof(buf)); |
if (ret <= 0) /* ret is the number of written bytes */ |
return false; |
307,22 → 292,11 |
int pos; |
map->total = 0; |
map->count = 0; |
for (pos = 0; (pos < ret / sizeof(uintptr_t)) && |
for (pos = 0; (pos < ret / sizeof(uint32_t)) && |
(map->count < MEMMAP_MAX_RECORDS); pos += ac + sc) { |
void *start = (void *) (buf[pos + ac - 1]); |
void * start = (void *) ((uintptr_t) buf[pos + ac - 1]); |
unsigned int size = buf[pos + ac + sc - 1]; |
/* |
* This is a hot fix of the issue which occurs on machines |
* where there are holes in the physical memory (such as |
* SunBlade 1500). Should we detect a hole in the physical |
* memory, we will ignore any memory detected behind |
* the hole and pretend the hole does not exist. |
*/ |
if ((map->count > 0) && (map->zones[map->count - 1].start + |
map->zones[map->count - 1].size < start)) |
break; |
if (size > 0) { |
map->zones[map->count].start = start; |
map->zones[map->count].size = size; |
334,13 → 308,13 |
return true; |
} |
int ofw_screen(screen_t *screen) |
{ |
char device_name[BUF_SIZE]; |
uint32_t virtaddr; |
if (ofw_get_property(ofw_aliases, "screen", device_name, |
sizeof(device_name)) <= 0) |
if (ofw_get_property(ofw_aliases, "screen", device_name, sizeof(device_name)) <= 0) |
return false; |
phandle device = ofw_find_device(device_name); |
347,78 → 321,27 |
if (device == -1) |
return false; |
if (ofw_get_property(device, "address", &virtaddr, |
sizeof(virtaddr)) <= 0) |
if (ofw_get_property(device, "address", &virtaddr, sizeof(virtaddr)) <= 0) |
return false; |
screen->addr = (void *) ((uintptr_t) virtaddr); |
if (ofw_get_property(device, "width", &screen->width, |
sizeof(screen->width)) <= 0) |
if (ofw_get_property(device, "width", &screen->width, sizeof(screen->width)) <= 0) |
return false; |
if (ofw_get_property(device, "height", &screen->height, |
sizeof(screen->height)) <= 0) |
if (ofw_get_property(device, "height", &screen->height, sizeof(screen->height)) <= 0) |
return false; |
if (ofw_get_property(device, "depth", &screen->bpp, |
sizeof(screen->bpp)) <= 0) |
if (ofw_get_property(device, "depth", &screen->bpp, sizeof(screen->bpp)) <= 0) |
return false; |
if (ofw_get_property(device, "linebytes", &screen->scanline, |
sizeof(screen->scanline)) <= 0) |
if (ofw_get_property(device, "linebytes", &screen->scanline, sizeof(screen->scanline)) <= 0) |
return false; |
return true; |
} |
#define RED(i) (((i) >> 5) & ((1 << 3) - 1)) |
#define GREEN(i) (((i) >> 3) & ((1 << 2) - 1)) |
#define BLUE(i) ((i) & ((1 << 3) - 1)) |
#define CLIP(i) ((i) <= 255 ? (i) : 255) |
/** |
* Sets up the palette for the 8-bit color depth configuration so that the |
* 3:2:3 color scheme can be used. Checks that setting the palette makes sense |
* (appropriate nodes exist in the OBP tree and the color depth is not greater |
* than 8). |
* |
* @return true if the palette has been set, false otherwise |
* |
*/ |
int ofw_setup_palette(void) |
{ |
char device_name[BUF_SIZE]; |
/* resolve alias */ |
if (ofw_get_property(ofw_aliases, "screen", device_name, |
sizeof(device_name)) <= 0) |
return false; |
/* for depth greater than 8 it makes no sense to set up the palette */ |
uint32_t depth; |
phandle device = ofw_find_device(device_name); |
if (device == -1) |
return false; |
if (ofw_get_property(device, "depth", &depth, sizeof(uint32_t)) <= 0) |
return false; |
if (depth != 8) |
return false; |
/* required in order to be able to make a method call */ |
ihandle screen = ofw_open(device_name); |
if (screen == -1) |
return false; |
/* setup the palette so that the (inverted) 3:2:3 scheme is usable */ |
unsigned int i; |
for (i = 0; i < 256; i++) |
ofw_call("call-method", 6, 1, NULL, "color!", screen, |
255 - i, CLIP(BLUE(i) * 37), GREEN(i) * 85, CLIP(RED(i) * 37)); |
return true; |
} |
void ofw_quiesce(void) |
{ |
ofw_call("quiesce", 0, 0, NULL); |
/branches/dd/boot/genarch/ofw_tree.c |
---|
42,11 → 42,10 |
static ofw_tree_property_t *ofw_tree_properties_alloc(unsigned count) |
{ |
return balloc(count * sizeof(ofw_tree_property_t), |
sizeof(ofw_tree_property_t)); |
return balloc(count * sizeof(ofw_tree_property_t), sizeof(ofw_tree_property_t)); |
} |
static void *ofw_tree_space_alloc(size_t size) |
static void * ofw_tree_space_alloc(size_t size) |
{ |
char *addr; |
66,26 → 65,23 |
return addr; |
} |
/** Transfer information from one OpenFirmware node into its memory |
* representation. |
/** Transfer information from one OpenFirmware node into its memory representation. |
* |
* Transfer entire information from the OpenFirmware device tree 'current' node |
* to its memory representation in 'current_node'. This function recursively |
* processes all node's children. Node's peers are processed iteratively in |
* order to prevent stack from overflowing. |
* Transfer entire information from the OpenFirmware device tree 'current' node to |
* its memory representation in 'current_node'. This function recursively processes |
* all node's children. Node's peers are processed iteratively in order to prevent |
* stack from overflowing. |
* |
* @param current_node Pointer to uninitialized ofw_tree_node structure that |
* will become the memory represenation of 'current'. |
* @param parent_node Parent ofw_tree_node structure or NULL in case of root |
* node. |
* @param current_node Pointer to uninitialized ofw_tree_node structure that will |
* become the memory represenation of 'current'. |
* @param parent_node Parent ofw_tree_node structure or NULL in case of root node. |
* @param current OpenFirmware phandle to the current device tree node. |
*/ |
static void ofw_tree_node_process(ofw_tree_node_t *current_node, |
ofw_tree_node_t *parent_node, phandle current) |
ofw_tree_node_t *parent_node, phandle current) |
{ |
static char path[MAX_PATH_LEN + 1]; |
static char path[MAX_PATH_LEN+1]; |
static char name[OFW_TREE_PROPERTY_MAX_NAMELEN]; |
static char name2[OFW_TREE_PROPERTY_MAX_NAMELEN]; |
phandle peer; |
phandle child; |
size_t len; |
125,6 → 121,7 |
memcpy(current_node->da_name, &path[i], len); |
current_node->da_name[len] = '\0'; |
/* |
* Recursively process the potential child node. |
*/ |
134,8 → 131,7 |
child_node = ofw_tree_node_alloc(); |
if (child_node) { |
ofw_tree_node_process(child_node, current_node, |
child); |
ofw_tree_node_process(child_node, current_node, child); |
current_node->child = child_node; |
} |
} |
144,11 → 140,9 |
* Count properties. |
*/ |
name[0] = '\0'; |
while (ofw_next_property(current, name, name2) == 1) { |
while (ofw_next_property(current, name, name) == 1) |
current_node->properties++; |
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); |
} |
if (!current_node->properties) |
return; |
155,23 → 149,20 |
/* |
* Copy properties. |
*/ |
current_node->property = |
ofw_tree_properties_alloc(current_node->properties); |
current_node->property = ofw_tree_properties_alloc(current_node->properties); |
if (!current_node->property) |
return; |
name[0] = '\0'; |
for (i = 0; ofw_next_property(current, name, name2) == 1; i++) { |
for (i = 0; ofw_next_property(current, name, name) == 1; i++) { |
size_t size; |
if (i == current_node->properties) |
break; |
memcpy(name, name2, OFW_TREE_PROPERTY_MAX_NAMELEN); |
memcpy(current_node->property[i].name, name, |
OFW_TREE_PROPERTY_MAX_NAMELEN); |
current_node->property[i].name[ |
OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; |
OFW_TREE_PROPERTY_MAX_NAMELEN); |
current_node->property[i].name[OFW_TREE_PROPERTY_MAX_NAMELEN] = '\0'; |
size = ofw_get_proplen(current, name); |
current_node->property[i].size = size; |
183,8 → 174,7 |
/* |
* Copy property value to memory node. |
*/ |
(void) ofw_get_property(current, name, |
buf, size); |
(void) ofw_get_property(current, name, buf, size); |
} |
} else { |
current_node->property[i].value = NULL; |
191,8 → 181,7 |
} |
} |
/* Just in case we ran out of memory. */ |
current_node->properties = i; |
current_node->properties = i; /* Just in case we ran out of memory. */ |
/* |
* Iteratively process the next peer node. |
225,33 → 214,15 |
/** Construct memory representation of OpenFirmware device tree. |
* |
* @return NULL on failure or pointer to the root node. |
* @return NULL on failure or pointer to the root node. |
*/ |
ofw_tree_node_t *ofw_tree_build(void) |
{ |
ofw_tree_node_t *root; |
phandle ssm_node; |
ofw_tree_node_t *ssm; |
root = ofw_tree_node_alloc(); |
if (root) |
ofw_tree_node_process(root, NULL, ofw_root); |
/* |
* The firmware client interface does not automatically include the |
* "ssm" node in the list of children of "/". A nasty yet working |
* solution is to explicitly stick "ssm" to the OFW tree. |
*/ |
ssm_node = ofw_find_device("/ssm@0,0"); |
if (ssm_node != -1) { |
ssm = ofw_tree_node_alloc(); |
if (ssm) { |
ofw_tree_node_process(ssm, root, |
ofw_find_device("/ssm@0,0")); |
ssm->peer = root->child; |
root->child = ssm; |
} |
} |
return root; |
} |
/branches/dd/boot/generic/macros.h |
---|
File deleted |
/branches/dd/boot/generic/align.h |
---|
26,7 → 26,7 |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
/** @addtogroup generic |
/** @addtogroup generic |
* @{ |
*/ |
/** @file |
/branches/dd/boot/generic/printf.c |
---|
83,16 → 83,14 |
*/ |
static void print_number(const unative_t num, const unsigned int base) |
{ |
int val = num; |
/* This is enough even for base 2. */ |
char d[sizeof(unative_t) * 8 + 1]; |
int val = num; |
char d[sizeof(unative_t) * 8 + 1]; /* this is good enough even for base == 2 */ |
int i = sizeof(unative_t) * 8 - 1; |
do { |
d[i--] = digits[val % base]; |
} while (val /= base); |
d[sizeof(unative_t) * 8] = 0; |
puts(&d[i + 1]); |
} |
158,89 → 156,89 |
int i = 0; |
va_list ap; |
char c; |
va_start(ap, fmt); |
while ((c = fmt[i++])) { |
switch (c) { |
/* control character */ |
case '%': |
switch (c = fmt[i++]) { |
/* percentile itself */ |
/* control character */ |
case '%': |
break; |
/* |
* String and character conversions. |
*/ |
case 's': |
puts(va_arg(ap, char_ptr)); |
goto loop; |
case 'c': |
c = (char) va_arg(ap, int); |
break; |
/* |
* Hexadecimal conversions with fixed width. |
*/ |
case 'P': |
puts("0x"); |
case 'p': |
print_fixed_hex(va_arg(ap, unative_t), |
sizeof(unative_t)); |
goto loop; |
case 'Q': |
puts("0x"); |
case 'q': |
print_fixed_hex(va_arg(ap, uint64_t), INT64); |
goto loop; |
case 'L': |
puts("0x"); |
case 'l': |
print_fixed_hex(va_arg(ap, unative_t), INT32); |
goto loop; |
case 'W': |
puts("0x"); |
case 'w': |
print_fixed_hex(va_arg(ap, unative_t), INT16); |
goto loop; |
case 'B': |
puts("0x"); |
case 'b': |
print_fixed_hex(va_arg(ap, unative_t), INT8); |
goto loop; |
/* |
* Decimal and hexadecimal conversions. |
*/ |
case 'd': |
print_number(va_arg(ap, unative_t), 10); |
goto loop; |
case 'X': |
puts("0x"); |
case 'x': |
print_number(va_arg(ap, unative_t), 16); |
goto loop; |
/* |
* Bad formatting. |
*/ |
switch (c = fmt[i++]) { |
/* percentile itself */ |
case '%': |
break; |
/* |
* String and character conversions. |
*/ |
case 's': |
puts(va_arg(ap, char_ptr)); |
goto loop; |
case 'c': |
c = (char) va_arg(ap, int); |
break; |
/* |
* Hexadecimal conversions with fixed width. |
*/ |
case 'P': |
puts("0x"); |
case 'p': |
print_fixed_hex(va_arg(ap, unative_t), sizeof(unative_t)); |
goto loop; |
case 'Q': |
puts("0x"); |
case 'q': |
print_fixed_hex(va_arg(ap, uint64_t), INT64); |
goto loop; |
case 'L': |
puts("0x"); |
case 'l': |
print_fixed_hex(va_arg(ap, unative_t), INT32); |
goto loop; |
case 'W': |
puts("0x"); |
case 'w': |
print_fixed_hex(va_arg(ap, unative_t), INT16); |
goto loop; |
case 'B': |
puts("0x"); |
case 'b': |
print_fixed_hex(va_arg(ap, unative_t), INT8); |
goto loop; |
/* |
* Decimal and hexadecimal conversions. |
*/ |
case 'd': |
print_number(va_arg(ap, unative_t), 10); |
goto loop; |
case 'X': |
puts("0x"); |
case 'x': |
print_number(va_arg(ap, unative_t), 16); |
goto loop; |
/* |
* Bad formatting. |
*/ |
default: |
goto out; |
} |
default: |
goto out; |
} |
default: |
write(&c, 1); |
write(&c, 1); |
} |
loop: |
; |
} |
/branches/dd/boot/generic/string.c |
---|
39,9 → 39,9 |
/** Return number of characters in a string. |
* |
* @param str NULL terminated string. |
* @param str NULL terminated string. |
* |
* @return Number of characters in str. |
* @return Number of characters in str. |
*/ |
size_t strlen(const char *str) |
{ |
53,17 → 53,16 |
return i; |
} |
/** Compare two NULL terminated strings. |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
* characters on the minimum of their lengths. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param src First string to compare. |
* @param dst Second string to compare. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, |
* 1 if second smaller. |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strcmp(const char *src, const char *dst) |
82,7 → 81,7 |
} |
/** Compare two NULL terminated strings. |
/** Compare two NULL terminated strings |
* |
* Do a char-by-char comparison of two NULL terminated strings. |
* The strings are considered equal iff they consist of the same |
89,12 → 88,11 |
* characters on the minimum of their lengths and specified maximal |
* length. |
* |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param len Maximal length for comparison. |
* @param src First string to compare. |
* @param dst Second string to compare. |
* @param len Maximal length for comparison. |
* |
* @return 0 if the strings are equal, -1 if first is smaller, |
* 1 if second smaller. |
* @return 0 if the strings are equal, -1 if first is smaller, 1 if second smaller. |
* |
*/ |
int strncmp(const char *src, const char *dst, size_t len) |
120,9 → 118,9 |
* If 'src' is shorter than 'len', '\0' is inserted behind the |
* last copied character. |
* |
* @param src Source string. |
* @param dest Destination buffer. |
* @param len Size of destination buffer. |
* @param src Source string. |
* @param dest Destination buffer. |
* @param len Size of destination buffer. |
*/ |
void strncpy(char *dest, const char *src, size_t len) |
{ |
134,13 → 132,13 |
dest[i-1] = '\0'; |
} |
/** Convert ascii representation to unative_t. |
/** Convert ascii representation to unative_t |
* |
* Supports 0x for hexa & 0 for octal notation. |
* Does not check for overflows, does not support negative numbers |
* |
* @param text Textual representation of number. |
* @return Converted number or 0 if no valid number found. |
* @param text Textual representation of number |
* @return Converted number or 0 if no valid number ofund |
*/ |
unative_t atoi(const char *text) |
{ |
154,9 → 152,9 |
base = 8; |
while (*text) { |
if (base != 16 && |
((*text >= 'A' && *text <= 'F') || |
(*text >='a' && *text <='f'))) |
if (base != 16 && \ |
((*text >= 'A' && *text <= 'F' ) |
|| (*text >='a' && *text <='f'))) |
break; |
if (base == 8 && *text >='8') |
break; |
178,28 → 176,5 |
return result; |
} |
/** Move piece of memory to another, possibly overlapping, location. |
* |
* @param dst Destination address. |
* @param src Source address. |
* @param len Number of bytes to move. |
* |
* @return Destination address. |
*/ |
void *memmove(void *dst, const void *src, size_t len) |
{ |
char *d = dst; |
const char *s = src; |
if (s < d) { |
while (len--) |
*(d + len) = *(s + len); |
} else { |
while (len--) |
*d++ = *s++; |
} |
return dst; |
} |
/** @} |
*/ |
/branches/dd/boot/generic/string.h |
---|
42,7 → 42,6 |
extern int strncmp(const char *src, const char *dst, size_t len); |
extern void strncpy(char *dest, const char *src, size_t len); |
extern unative_t atoi(const char *text); |
extern void *memmove(void *dst, const void *src, size_t len); |
#endif |
/branches/dd/boot/tools/pack.py |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/boot/tools/ia32/gen_vga323.c |
---|
1,36 → 1,8 |
/* |
* Copyright (c) 2008 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include <stdio.h> |
#define RED(i) (((i) >> 5) & ((1 << 3) - 1)) |
#define GREEN(i) (((i) >> 3) & ((1 << 2) - 1)) |
#define BLUE(i) ((i) & ((1 << 3) - 1)) |
#define RED(i) ((i >> 5) & ((1 << 3) - 1)) |
#define GREEN(i) ((i >> 3) & ((1 << 2) - 1)) |
#define BLUE(i) (i & ((1 << 3) - 1)) |
int main(int argc, char *argv[]) { |
unsigned int i; |
/branches/dd/boot/tools/ppc32/font-8x16.h |
---|
0,0 → 1,38 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#ifndef __FONT_8X16_H__ |
#define __FONT_8X16_H__ |
#define FONT_GLIPHS 256 |
#define FONT_SCANLINES 16 |
#define FONT_WIDTH 8 |
extern unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES]; |
#endif |
/branches/dd/boot/tools/ppc32/font-8x16.c |
---|
0,0 → 1,4641 |
/* |
* Copyright (c) 2005 Martin Decky |
* All rights reserved. |
* |
* Redistribution and use in source and binary forms, with or without |
* modification, are permitted provided that the following conditions |
* are met: |
* |
* - Redistributions of source code must retain the above copyright |
* notice, this list of conditions and the following disclaimer. |
* - 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. |
* - The name of the author may not be used to endorse or promote products |
* derived from this software without specific prior written permission. |
* |
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
*/ |
#include "font-8x16.h" |
unsigned char fb_font[FONT_GLIPHS * FONT_SCANLINES] = { |
/* 0 0x00 '^@' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 1 0x01 '^A' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x81, /* 10000001 */ |
0xa5, /* 10100101 */ |
0x81, /* 10000001 */ |
0x81, /* 10000001 */ |
0xbd, /* 10111101 */ |
0x99, /* 10011001 */ |
0x81, /* 10000001 */ |
0x81, /* 10000001 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 2 0x02 '^B' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0xff, /* 11111111 */ |
0xdb, /* 11011011 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xc3, /* 11000011 */ |
0xe7, /* 11100111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 3 0x03 '^C' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x6c, /* 01101100 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0x7c, /* 01111100 */ |
0x38, /* 00111000 */ |
0x10, /* 00010000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 4 0x04 '^D' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x7c, /* 01111100 */ |
0xfe, /* 11111110 */ |
0x7c, /* 01111100 */ |
0x38, /* 00111000 */ |
0x10, /* 00010000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 5 0x05 '^E' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0xe7, /* 11100111 */ |
0xe7, /* 11100111 */ |
0xe7, /* 11100111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 6 0x06 '^F' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x7e, /* 01111110 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 7 0x07 '^G' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 8 0x08 '^H' */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xe7, /* 11100111 */ |
0xc3, /* 11000011 */ |
0xc3, /* 11000011 */ |
0xe7, /* 11100111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
/* 9 0x09 '^I' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x42, /* 01000010 */ |
0x42, /* 01000010 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 10 0x0a '^J' */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xc3, /* 11000011 */ |
0x99, /* 10011001 */ |
0xbd, /* 10111101 */ |
0xbd, /* 10111101 */ |
0x99, /* 10011001 */ |
0xc3, /* 11000011 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
/* 11 0x0b '^K' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1e, /* 00011110 */ |
0x0e, /* 00001110 */ |
0x1a, /* 00011010 */ |
0x32, /* 00110010 */ |
0x78, /* 01111000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 12 0x0c '^L' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 13 0x0d '^M' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3f, /* 00111111 */ |
0x33, /* 00110011 */ |
0x3f, /* 00111111 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x70, /* 01110000 */ |
0xf0, /* 11110000 */ |
0xe0, /* 11100000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 14 0x0e '^N' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7f, /* 01111111 */ |
0x63, /* 01100011 */ |
0x7f, /* 01111111 */ |
0x63, /* 01100011 */ |
0x63, /* 01100011 */ |
0x63, /* 01100011 */ |
0x63, /* 01100011 */ |
0x67, /* 01100111 */ |
0xe7, /* 11100111 */ |
0xe6, /* 11100110 */ |
0xc0, /* 11000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 15 0x0f '^O' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xdb, /* 11011011 */ |
0x3c, /* 00111100 */ |
0xe7, /* 11100111 */ |
0x3c, /* 00111100 */ |
0xdb, /* 11011011 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 16 0x10 '^P' */ |
0x00, /* 00000000 */ |
0x80, /* 10000000 */ |
0xc0, /* 11000000 */ |
0xe0, /* 11100000 */ |
0xf0, /* 11110000 */ |
0xf8, /* 11111000 */ |
0xfe, /* 11111110 */ |
0xf8, /* 11111000 */ |
0xf0, /* 11110000 */ |
0xe0, /* 11100000 */ |
0xc0, /* 11000000 */ |
0x80, /* 10000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 17 0x11 '^Q' */ |
0x00, /* 00000000 */ |
0x02, /* 00000010 */ |
0x06, /* 00000110 */ |
0x0e, /* 00001110 */ |
0x1e, /* 00011110 */ |
0x3e, /* 00111110 */ |
0xfe, /* 11111110 */ |
0x3e, /* 00111110 */ |
0x1e, /* 00011110 */ |
0x0e, /* 00001110 */ |
0x06, /* 00000110 */ |
0x02, /* 00000010 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 18 0x12 '^R' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 19 0x13 '^S' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 20 0x14 '^T' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7f, /* 01111111 */ |
0xdb, /* 11011011 */ |
0xdb, /* 11011011 */ |
0xdb, /* 11011011 */ |
0x7b, /* 01111011 */ |
0x1b, /* 00011011 */ |
0x1b, /* 00011011 */ |
0x1b, /* 00011011 */ |
0x1b, /* 00011011 */ |
0x1b, /* 00011011 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 21 0x15 '^U' */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0x60, /* 01100000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x0c, /* 00001100 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 22 0x16 '^V' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 23 0x17 '^W' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 24 0x18 '^X' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 25 0x19 '^Y' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 26 0x1a '^Z' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0xfe, /* 11111110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 27 0x1b '^[' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xfe, /* 11111110 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 28 0x1c '^\' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 29 0x1d '^]' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x28, /* 00101000 */ |
0x6c, /* 01101100 */ |
0xfe, /* 11111110 */ |
0x6c, /* 01101100 */ |
0x28, /* 00101000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 30 0x1e '^^' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x38, /* 00111000 */ |
0x7c, /* 01111100 */ |
0x7c, /* 01111100 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 31 0x1f '^_' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0x7c, /* 01111100 */ |
0x7c, /* 01111100 */ |
0x38, /* 00111000 */ |
0x38, /* 00111000 */ |
0x10, /* 00010000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 32 0x20 ' ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 33 0x21 '!' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 34 0x22 '"' */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x24, /* 00100100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 35 0x23 '#' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0xfe, /* 11111110 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0xfe, /* 11111110 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 36 0x24 '$' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc2, /* 11000010 */ |
0xc0, /* 11000000 */ |
0x7c, /* 01111100 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x86, /* 10000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 37 0x25 '%' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc2, /* 11000010 */ |
0xc6, /* 11000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc6, /* 11000110 */ |
0x86, /* 10000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 38 0x26 '&' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 39 0x27 ''' */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 40 0x28 '(' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 41 0x29 ')' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 42 0x2a '*' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0xff, /* 11111111 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 43 0x2b '+' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 44 0x2c ',' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 45 0x2d '-' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 46 0x2e '.' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 47 0x2f '/' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x02, /* 00000010 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0x80, /* 10000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 48 0x30 '0' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 49 0x31 '1' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x38, /* 00111000 */ |
0x78, /* 01111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 50 0x32 '2' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 51 0x33 '3' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x3c, /* 00111100 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 52 0x34 '4' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x0c, /* 00001100 */ |
0x1c, /* 00011100 */ |
0x3c, /* 00111100 */ |
0x6c, /* 01101100 */ |
0xcc, /* 11001100 */ |
0xfe, /* 11111110 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x1e, /* 00011110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 53 0x35 '5' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xfc, /* 11111100 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 54 0x36 '6' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xfc, /* 11111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 55 0x37 '7' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 56 0x38 '8' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 57 0x39 '9' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7e, /* 01111110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 58 0x3a ':' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 59 0x3b ';' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 60 0x3c '<' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x06, /* 00000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 61 0x3d '=' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 62 0x3e '>' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 63 0x3f '?' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 64 0x40 '@' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xde, /* 11011110 */ |
0xde, /* 11011110 */ |
0xde, /* 11011110 */ |
0xdc, /* 11011100 */ |
0xc0, /* 11000000 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 65 0x41 'A' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 66 0x42 'B' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfc, /* 11111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0xfc, /* 11111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 67 0x43 'C' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0xc2, /* 11000010 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc2, /* 11000010 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 68 0x44 'D' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xf8, /* 11111000 */ |
0x6c, /* 01101100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x6c, /* 01101100 */ |
0xf8, /* 11111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 69 0x45 'E' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x66, /* 01100110 */ |
0x62, /* 01100010 */ |
0x68, /* 01101000 */ |
0x78, /* 01111000 */ |
0x68, /* 01101000 */ |
0x60, /* 01100000 */ |
0x62, /* 01100010 */ |
0x66, /* 01100110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 70 0x46 'F' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x66, /* 01100110 */ |
0x62, /* 01100010 */ |
0x68, /* 01101000 */ |
0x78, /* 01111000 */ |
0x68, /* 01101000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xf0, /* 11110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 71 0x47 'G' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0xc2, /* 11000010 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xde, /* 11011110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x66, /* 01100110 */ |
0x3a, /* 00111010 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 72 0x48 'H' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 73 0x49 'I' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 74 0x4a 'J' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1e, /* 00011110 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 75 0x4b 'K' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xe6, /* 11100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x6c, /* 01101100 */ |
0x78, /* 01111000 */ |
0x78, /* 01111000 */ |
0x6c, /* 01101100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0xe6, /* 11100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 76 0x4c 'L' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xf0, /* 11110000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x62, /* 01100010 */ |
0x66, /* 01100110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 77 0x4d 'M' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xee, /* 11101110 */ |
0xfe, /* 11111110 */ |
0xfe, /* 11111110 */ |
0xd6, /* 11010110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 78 0x4e 'N' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xe6, /* 11100110 */ |
0xf6, /* 11110110 */ |
0xfe, /* 11111110 */ |
0xde, /* 11011110 */ |
0xce, /* 11001110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 79 0x4f 'O' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 80 0x50 'P' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfc, /* 11111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xf0, /* 11110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 81 0x51 'Q' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xd6, /* 11010110 */ |
0xde, /* 11011110 */ |
0x7c, /* 01111100 */ |
0x0c, /* 00001100 */ |
0x0e, /* 00001110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 82 0x52 'R' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfc, /* 11111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x6c, /* 01101100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0xe6, /* 11100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 83 0x53 'S' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x60, /* 01100000 */ |
0x38, /* 00111000 */ |
0x0c, /* 00001100 */ |
0x06, /* 00000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 84 0x54 'T' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x5a, /* 01011010 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 85 0x55 'U' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 86 0x56 'V' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x10, /* 00010000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 87 0x57 'W' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xfe, /* 11111110 */ |
0xee, /* 11101110 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 88 0x58 'X' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x7c, /* 01111100 */ |
0x38, /* 00111000 */ |
0x38, /* 00111000 */ |
0x7c, /* 01111100 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 89 0x59 'Y' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 90 0x5a 'Z' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0x86, /* 10000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc2, /* 11000010 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 91 0x5b '[' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 92 0x5c '\' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x80, /* 10000000 */ |
0xc0, /* 11000000 */ |
0xe0, /* 11100000 */ |
0x70, /* 01110000 */ |
0x38, /* 00111000 */ |
0x1c, /* 00011100 */ |
0x0e, /* 00001110 */ |
0x06, /* 00000110 */ |
0x02, /* 00000010 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 93 0x5d ']' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 94 0x5e '^' */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 95 0x5f '_' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 96 0x60 '`' */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 97 0x61 'a' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 98 0x62 'b' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xe0, /* 11100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x78, /* 01111000 */ |
0x6c, /* 01101100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 99 0x63 'c' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 100 0x64 'd' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1c, /* 00011100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x3c, /* 00111100 */ |
0x6c, /* 01101100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 101 0x65 'e' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 102 0x66 'f' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1c, /* 00011100 */ |
0x36, /* 00110110 */ |
0x32, /* 00110010 */ |
0x30, /* 00110000 */ |
0x78, /* 01111000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 103 0x67 'g' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x7c, /* 01111100 */ |
0x0c, /* 00001100 */ |
0xcc, /* 11001100 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
/* 104 0x68 'h' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xe0, /* 11100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x6c, /* 01101100 */ |
0x76, /* 01110110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0xe6, /* 11100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 105 0x69 'i' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 106 0x6a 'j' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x00, /* 00000000 */ |
0x0e, /* 00001110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
/* 107 0x6b 'k' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xe0, /* 11100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x66, /* 01100110 */ |
0x6c, /* 01101100 */ |
0x78, /* 01111000 */ |
0x78, /* 01111000 */ |
0x6c, /* 01101100 */ |
0x66, /* 01100110 */ |
0xe6, /* 11100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 108 0x6c 'l' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 109 0x6d 'm' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xec, /* 11101100 */ |
0xfe, /* 11111110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 110 0x6e 'n' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xdc, /* 11011100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 111 0x6f 'o' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 112 0x70 'p' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xdc, /* 11011100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xf0, /* 11110000 */ |
0x00, /* 00000000 */ |
/* 113 0x71 'q' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x7c, /* 01111100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x1e, /* 00011110 */ |
0x00, /* 00000000 */ |
/* 114 0x72 'r' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xdc, /* 11011100 */ |
0x76, /* 01110110 */ |
0x66, /* 01100110 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xf0, /* 11110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 115 0x73 's' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0x60, /* 01100000 */ |
0x38, /* 00111000 */ |
0x0c, /* 00001100 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 116 0x74 't' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0xfc, /* 11111100 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x36, /* 00110110 */ |
0x1c, /* 00011100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 117 0x75 'u' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 118 0x76 'v' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 119 0x77 'w' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xd6, /* 11010110 */ |
0xfe, /* 11111110 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 120 0x78 'x' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x38, /* 00111000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 121 0x79 'y' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7e, /* 01111110 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0xf8, /* 11111000 */ |
0x00, /* 00000000 */ |
/* 122 0x7a 'z' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xcc, /* 11001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 123 0x7b '{' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x0e, /* 00001110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x70, /* 01110000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x0e, /* 00001110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 124 0x7c '|' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 125 0x7d '}' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x70, /* 01110000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x0e, /* 00001110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 126 0x7e '~' */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 127 0x7f '' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 128 0x80 '€' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0xc2, /* 11000010 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc2, /* 11000010 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 129 0x81 '' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 130 0x82 '‚' */ |
0x00, /* 00000000 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 131 0x83 'ƒ' */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 132 0x84 '„' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 133 0x85 '…' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 134 0x86 '†' */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 135 0x87 '‡' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x18, /* 00011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 136 0x88 'ˆ' */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 137 0x89 '‰' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 138 0x8a 'Š' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 139 0x8b '‹' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 140 0x8c 'Œ' */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 141 0x8d '' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 142 0x8e 'Ž' */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 143 0x8f '' */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 144 0x90 '' */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x66, /* 01100110 */ |
0x62, /* 01100010 */ |
0x68, /* 01101000 */ |
0x78, /* 01111000 */ |
0x68, /* 01101000 */ |
0x62, /* 01100010 */ |
0x66, /* 01100110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 145 0x91 '‘' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xec, /* 11101100 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x7e, /* 01111110 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0x6e, /* 01101110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 146 0x92 '’' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3e, /* 00111110 */ |
0x6c, /* 01101100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xfe, /* 11111110 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xce, /* 11001110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 147 0x93 '“' */ |
0x00, /* 00000000 */ |
0x10, /* 00010000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 148 0x94 '”' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 149 0x95 '•' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 150 0x96 '–' */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x78, /* 01111000 */ |
0xcc, /* 11001100 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 151 0x97 '—' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 152 0x98 '˜' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7e, /* 01111110 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x78, /* 01111000 */ |
0x00, /* 00000000 */ |
/* 153 0x99 '™' */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 154 0x9a 'š' */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 155 0x9b '›' */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 156 0x9c 'œ' */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x64, /* 01100100 */ |
0x60, /* 01100000 */ |
0xf0, /* 11110000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xe6, /* 11100110 */ |
0xfc, /* 11111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 157 0x9d '' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 158 0x9e 'ž' */ |
0x00, /* 00000000 */ |
0xf8, /* 11111000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xf8, /* 11111000 */ |
0xc4, /* 11000100 */ |
0xcc, /* 11001100 */ |
0xde, /* 11011110 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 159 0x9f 'Ÿ' */ |
0x00, /* 00000000 */ |
0x0e, /* 00001110 */ |
0x1b, /* 00011011 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xd8, /* 11011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 160 0xa0 ' ' */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0x0c, /* 00001100 */ |
0x7c, /* 01111100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 161 0xa1 '¡' */ |
0x00, /* 00000000 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 162 0xa2 '¢' */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 163 0xa3 '£' */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x00, /* 00000000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 164 0xa4 '¤' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x00, /* 00000000 */ |
0xdc, /* 11011100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 165 0xa5 '¥' */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x00, /* 00000000 */ |
0xc6, /* 11000110 */ |
0xe6, /* 11100110 */ |
0xf6, /* 11110110 */ |
0xfe, /* 11111110 */ |
0xde, /* 11011110 */ |
0xce, /* 11001110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 166 0xa6 '¦' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x3e, /* 00111110 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 167 0xa7 '§' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 168 0xa8 '¨' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x7c, /* 01111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 169 0xa9 '©' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 170 0xaa 'ª' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 171 0xab '«' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0xe0, /* 11100000 */ |
0x62, /* 01100010 */ |
0x66, /* 01100110 */ |
0x6c, /* 01101100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xdc, /* 11011100 */ |
0x86, /* 10000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x3e, /* 00111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 172 0xac '¬' */ |
0x00, /* 00000000 */ |
0x60, /* 01100000 */ |
0xe0, /* 11100000 */ |
0x62, /* 01100010 */ |
0x66, /* 01100110 */ |
0x6c, /* 01101100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x66, /* 01100110 */ |
0xce, /* 11001110 */ |
0x9a, /* 10011010 */ |
0x3f, /* 00111111 */ |
0x06, /* 00000110 */ |
0x06, /* 00000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 173 0xad '' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 174 0xae '®' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x36, /* 00110110 */ |
0x6c, /* 01101100 */ |
0xd8, /* 11011000 */ |
0x6c, /* 01101100 */ |
0x36, /* 00110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 175 0xaf '¯' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xd8, /* 11011000 */ |
0x6c, /* 01101100 */ |
0x36, /* 00110110 */ |
0x6c, /* 01101100 */ |
0xd8, /* 11011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 176 0xb0 '°' */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
0x11, /* 00010001 */ |
0x44, /* 01000100 */ |
/* 177 0xb1 '±' */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
0x55, /* 01010101 */ |
0xaa, /* 10101010 */ |
/* 178 0xb2 '²' */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
0xdd, /* 11011101 */ |
0x77, /* 01110111 */ |
/* 179 0xb3 '³' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 180 0xb4 '´' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 181 0xb5 'µ' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 182 0xb6 '¶' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xf6, /* 11110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 183 0xb7 '·' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 184 0xb8 '¸' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 185 0xb9 '¹' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xf6, /* 11110110 */ |
0x06, /* 00000110 */ |
0xf6, /* 11110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 186 0xba 'º' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 187 0xbb '»' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x06, /* 00000110 */ |
0xf6, /* 11110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 188 0xbc '¼' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xf6, /* 11110110 */ |
0x06, /* 00000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 189 0xbd '½' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 190 0xbe '¾' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 191 0xbf '¿' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xf8, /* 11111000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 192 0xc0 'À' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 193 0xc1 'Á' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 194 0xc2 'Â' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 195 0xc3 'Ã' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 196 0xc4 'Ä' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 197 0xc5 'Å' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xff, /* 11111111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 198 0xc6 'Æ' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 199 0xc7 'Ç' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x37, /* 00110111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 200 0xc8 'È' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x37, /* 00110111 */ |
0x30, /* 00110000 */ |
0x3f, /* 00111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 201 0xc9 'É' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3f, /* 00111111 */ |
0x30, /* 00110000 */ |
0x37, /* 00110111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 202 0xca 'Ê' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xf7, /* 11110111 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 203 0xcb 'Ë' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0xf7, /* 11110111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 204 0xcc 'Ì' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x37, /* 00110111 */ |
0x30, /* 00110000 */ |
0x37, /* 00110111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 205 0xcd 'Í' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 206 0xce 'Î' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xf7, /* 11110111 */ |
0x00, /* 00000000 */ |
0xf7, /* 11110111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 207 0xcf 'Ï' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 208 0xd0 'Ð' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 209 0xd1 'Ñ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 210 0xd2 'Ò' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 211 0xd3 'Ó' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x3f, /* 00111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 212 0xd4 'Ô' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 213 0xd5 'Õ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 214 0xd6 'Ö' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x3f, /* 00111111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 215 0xd7 '×' */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0xff, /* 11111111 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
/* 216 0xd8 'Ø' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xff, /* 11111111 */ |
0x18, /* 00011000 */ |
0xff, /* 11111111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 217 0xd9 'Ù' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xf8, /* 11111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 218 0xda 'Ú' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1f, /* 00011111 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 219 0xdb 'Û' */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
/* 220 0xdc 'Ü' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
/* 221 0xdd 'Ý' */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
0xf0, /* 11110000 */ |
/* 222 0xde 'Þ' */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
0x0f, /* 00001111 */ |
/* 223 0xdf 'ß' */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0xff, /* 11111111 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 224 0xe0 'à' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xdc, /* 11011100 */ |
0x76, /* 01110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 225 0xe1 'á' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x78, /* 01111000 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xcc, /* 11001100 */ |
0xd8, /* 11011000 */ |
0xcc, /* 11001100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xcc, /* 11001100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 226 0xe2 'â' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0xc0, /* 11000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 227 0xe3 'ã' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 228 0xe4 'ä' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 229 0xe5 'å' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 230 0xe6 'æ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x7c, /* 01111100 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0x00, /* 00000000 */ |
/* 231 0xe7 'ç' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 232 0xe8 'è' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 233 0xe9 'é' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xfe, /* 11111110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 234 0xea 'ê' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0xee, /* 11101110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 235 0xeb 'ë' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1e, /* 00011110 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x3e, /* 00111110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x66, /* 01100110 */ |
0x3c, /* 00111100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 236 0xec 'ì' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0xdb, /* 11011011 */ |
0xdb, /* 11011011 */ |
0xdb, /* 11011011 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 237 0xed 'í' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x03, /* 00000011 */ |
0x06, /* 00000110 */ |
0x7e, /* 01111110 */ |
0xdb, /* 11011011 */ |
0xdb, /* 11011011 */ |
0xf3, /* 11110011 */ |
0x7e, /* 01111110 */ |
0x60, /* 01100000 */ |
0xc0, /* 11000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 238 0xee 'î' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x1c, /* 00011100 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x7c, /* 01111100 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x1c, /* 00011100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 239 0xef 'ï' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7c, /* 01111100 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0xc6, /* 11000110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 240 0xf0 'ð' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0xfe, /* 11111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 241 0xf1 'ñ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x7e, /* 01111110 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 242 0xf2 'ò' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x06, /* 00000110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 243 0xf3 'ó' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x30, /* 00110000 */ |
0x60, /* 01100000 */ |
0x30, /* 00110000 */ |
0x18, /* 00011000 */ |
0x0c, /* 00001100 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 244 0xf4 'ô' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x0e, /* 00001110 */ |
0x1b, /* 00011011 */ |
0x1b, /* 00011011 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
/* 245 0xf5 'õ' */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0xd8, /* 11011000 */ |
0x70, /* 01110000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 246 0xf6 'ö' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 247 0xf7 '÷' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x00, /* 00000000 */ |
0x76, /* 01110110 */ |
0xdc, /* 11011100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 248 0xf8 'ø' */ |
0x00, /* 00000000 */ |
0x38, /* 00111000 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x38, /* 00111000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 249 0xf9 'ù' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 250 0xfa 'ú' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x18, /* 00011000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 251 0xfb 'û' */ |
0x00, /* 00000000 */ |
0x0f, /* 00001111 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0x0c, /* 00001100 */ |
0xec, /* 11101100 */ |
0x6c, /* 01101100 */ |
0x6c, /* 01101100 */ |
0x3c, /* 00111100 */ |
0x1c, /* 00011100 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 252 0xfc 'ü' */ |
0x00, /* 00000000 */ |
0x6c, /* 01101100 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x36, /* 00110110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 253 0xfd 'ý' */ |
0x00, /* 00000000 */ |
0x3c, /* 00111100 */ |
0x66, /* 01100110 */ |
0x0c, /* 00001100 */ |
0x18, /* 00011000 */ |
0x32, /* 00110010 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 254 0xfe 'þ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x7e, /* 01111110 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
/* 255 0xff 'ÿ' */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
0x00, /* 00000000 */ |
}; |
/branches/dd/boot/tools/ppc32/debug.c |
---|
0,0 → 1,68 |
#include "font-8x16.h" |
#define FB_REG "r8" |
#define SCAN_REG "r9" |
#define ADDR_REG "r10" |
#define FG_REG "r11" |
#define BG_REG "r12" |
#define FG_COLOR 0xffffffff |
#define BG_COLOR 0x00000000 |
#define BPP 4 |
void print_macro_init(void) { |
printf(".macro DEBUG_INIT\n"); |
printf("#ifdef CONFIG_DEBUG\n"); |
printf("\tlis %s, %d\n", FG_REG, FG_COLOR >> 16); |
printf("\tori %s, %s, %d\n", FG_REG, FG_REG, FG_COLOR & 0xffff); |
printf("\t\n"); |
printf("\tlis %s, %d\n", BG_REG, BG_COLOR >> 16); |
printf("\tori %s, %s, %d\n", BG_REG, BG_REG, BG_COLOR & 0xffff); |
printf("\t\n"); |
printf("\tmr %s, %s\n", ADDR_REG, FB_REG); |
printf("#endif\n"); |
printf(".endm\n"); |
} |
void print_macro(const char *name) { |
printf(".macro DEBUG_%s\n", name); |
printf("#ifdef CONFIG_DEBUG\n"); |
unsigned int y; |
for (y = 0; y < FONT_SCANLINES; y++) { |
printf("\t\n"); |
if (y > 0) |
printf("\tadd %s, %s, %s\n", ADDR_REG, ADDR_REG, SCAN_REG); |
unsigned int i; |
for (i = 0; name[i] != 0; i++) { |
char c = name[i]; |
unsigned int x; |
for (x = 0; x < FONT_WIDTH; x++) { |
if (((fb_font[c * FONT_SCANLINES + y] >> (FONT_WIDTH - x)) & 1) == 1) |
printf("\tstw %s, %d(%s)\n", FG_REG, (i * FONT_WIDTH + x) * BPP, ADDR_REG); |
else |
printf("\tstw %s, %d(%s)\n", BG_REG, (i * FONT_WIDTH + x) * BPP, ADDR_REG); |
} |
} |
} |
printf("#endif\n"); |
printf(".endm\n"); |
} |
int main(int argc, char *argv[]) { |
print_macro_init(); |
int i; |
for (i = 1; i < argc; i++) { |
printf("\n"); |
print_macro(argv[i]); |
} |
return 0; |
} |
/branches/dd/boot/tools/ppc32/Makefile |
---|
0,0 → 1,8 |
debug: debug.o font-8x16.o |
gcc -o debug debug.o font-8x16.o |
debug.o: debug.c font-8x16.h |
gcc -c -o debug.o debug.c |
font-8x16.o: font-8x16.c font-8x16.h |
gcc -c -o font-8x16.o font-8x16.c |
/branches/dd/boot/tools/ia64/vmaxlma.c |
---|
0,0 → 1,75 |
/* |
* Swap VMA and LMA in ELF header. |
* |
* by Jakub Jermar <jermar@itbs.cz> |
* |
* GPL'ed, copyleft |
*/ |
/* |
* HP's IA-64 simulator Ski seems to confuse VMA and LMA in the ELF header. |
* Instead of using LMA, Ski loads sections at their VMA addresses. |
* This short program provides a workaround for this bug by simply |
* swapping VMA and LMA in the ELF header of the executable. |
* |
* Note that after applying this workaround, you will be able to load |
* ELF objects with different VMA and LMA in Ski, but the executable |
* will become wronged for other potential uses. |
*/ |
#include <stdio.h> |
#include <stdlib.h> |
#include <sys/types.h> |
#include <sys/stat.h> |
#include <sys/mman.h> |
#include <unistd.h> |
#include <fcntl.h> |
void syntax(char *prg) |
{ |
printf("%s ELF-file\n", prg); |
exit(1); |
} |
void error(char *msg) |
{ |
printf("Error: %s\n", msg); |
exit(2); |
} |
#define ELF_VMA (0x50/sizeof(unsigned long long)) |
#define ELF_LMA (0x58/sizeof(unsigned long long)) |
#define ELF_ENTRY (0x18/sizeof(unsigned long long)) |
#define LENGTH 0x98 |
int main(int argc, char *argv[]) |
{ |
int fd; |
unsigned long long vma, lma,entry; |
unsigned long long *elf; |
if (argc != 2) |
syntax(argv[0]); |
fd = open(argv[1], O_RDWR); |
if (fd == -1) |
error("open failed"); |
elf = mmap(NULL, LENGTH, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); |
if ((void *) elf == (void *) -1) |
error("map failed"); |
lma = elf[ELF_LMA]; |
elf[ELF_VMA] = lma; |
entry = lma; |
elf[ELF_ENTRY] = entry; |
if (munmap(elf, LENGTH) == -1) |
error("munmap failed"); |
if (close(fd) == -1) |
error("close failed"); |
return 0; |
} |
/branches/dd/boot/Makefile |
---|
29,8 → 29,7 |
## Include configuration |
# |
-include ../Makefile.config |
-include ../config.defs |
-include Makefile.config |
## Paths |
# |
39,11 → 38,31 |
KERNELDIR = $(BASE)/kernel |
USPACEDIR = $(BASE)/uspace |
.PHONY: all build clean generic_clean |
ifeq ($(CONFIG_DEBUG),y) |
DEFS += -DCONFIG_DEBUG |
endif |
all: ../Makefile.config ../config.h ../config.defs build |
ifeq ($(CONFIG_BAT),y) |
DEFS += -DCONFIG_BAT |
endif |
-include arch/$(BARCH)/Makefile.inc |
ifeq ($(CONFIG_SMP),y) |
DEFS += -DCONFIG_SMP |
endif |
.PHONY: all build config distclean clean generic_clean |
all: |
../tools/config.py boot.config default $(ARCH) $(COMPILER) $(CONFIG_DEBUG) $(IMAGE) |
$(MAKE) -C . build |
-include arch/$(ARCH)/Makefile.inc |
config: |
../tools/config.py boot.config |
distclean: clean |
-rm Makefile.config |
generic_clean: |
-rm generic/*.o genarch/*.o |
/branches/dd/version |
---|
1,42 → 1,8 |
# |
# Copyright (c) 2006 Martin Decky |
# All rights reserved. |
# |
# Redistribution and use in source and binary forms, with or without |
# modification, are permitted provided that the following conditions |
# are met: |
# |
# - Redistributions of source code must retain the above copyright |
# notice, this list of conditions and the following disclaimer. |
# - 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. |
# - The name of the author may not be used to endorse or promote products |
# derived from this software without specific prior written permission. |
# |
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR |
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES |
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. |
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, |
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT |
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
# |
## This file defines the release information of HelenOS. |
# |
# The release string RELEASE consists of three or four components |
# (version, patch level, sublevel and optionally an extra level). |
# |
# The NAME string is the code name of the given release. |
# |
VERSION = 0 |
PATCHLEVEL = 4 |
PATCHLEVEL = 3 |
SUBLEVEL = 0 |
#EXTRAVERSION = 0 |
NAME = Tartare |
ifdef EXTRAVERSION |
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL).$(EXTRAVERSION) |
43,5 → 9,3 |
else |
RELEASE = $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) |
endif |
NAME = Sinister Valentine |
/branches/dd/contrib/util/DownloadAndPatchSILO.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/contrib/default/ppc32/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/ppc32/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/amd64/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/amd64/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/mips32/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/mips32/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/ia32/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/ia32/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/sparc64/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/sparc64/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/ia64/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/ia64/Makefile.config |
---|
File deleted |
/branches/dd/contrib/default/arm32/output |
---|
File deleted |
\ No newline at end of file |
/branches/dd/contrib/default/arm32/Makefile.config |
---|
File deleted |
/branches/dd/contrib/toolchain/toolchain.sparc64.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.3" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="sparc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.ppc32.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="ppc" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.amd64.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="amd64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.ppc64.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="ppc64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.ia32.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="i686" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.mipsel32.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="mipsel" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.ia64.sh |
---|
15,18 → 15,16 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
INCLUDES="ia64-pc-gnu-linux_includes.tar.bz2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
GCC_CPP="gcc-g++-${GCC_VERSION}.tar.bz2" |
INCLUDES_SOURCE="http://download.decky.cz/" |
BINUTILS_SOURCE="ftp://ftp.gnu.org/gnu/binutils/" |
GCC_SOURCE="ftp://ftp.gnu.org/gnu/gcc/gcc-${GCC_VERSION}/" |
33,7 → 31,7 |
PLATFORM="ia64" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-pc-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
INCLUDESDIR="${WORKDIR}/include" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
41,6 → 39,10 |
echo ">>> Downloading tarballs" |
if [ ! -f "${INCLUDES}" ]; then |
wget -c "${INCLUDES_SOURCE}${INCLUDES}" |
check_error $? "Error downloading includes." |
fi |
if [ ! -f "${BINUTILS}" ]; then |
wget -c "${BINUTILS_SOURCE}${BINUTILS}" |
check_error $? "Error downloading binutils." |
73,6 → 75,8 |
fi |
echo ">>> Unpacking tarballs" |
tar -xvjf "${INCLUDES}" |
check_error $? "Error unpacking includes." |
tar -xvzf "${BINUTILS}" |
check_error $? "Error unpacking binutils." |
tar -xvjf "${GCC_CORE}" |
93,7 → 97,7 |
echo ">>> Compiling and installing GCC" |
cd "${OBJDIR}" |
check_error $? "Change directory failed." |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj --disable-shared |
"${GCCDIR}/configure" "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" --with-gnu-as --with-gnu-ld --disable-nls --disable-threads --enable-languages=c,objc,c++,obj-c++ --disable-multilib --disable-libgcj "--with-headers=${INCLUDESDIR}" --disable-shared |
check_error $? "Error configuring GCC." |
PATH="${PATH}:${PREFIX}/bin" make all-gcc install-gcc |
check_error $? "Error compiling/installing GCC." |
/branches/dd/contrib/toolchain/toolchain.arm32.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="arm" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-linux-gnu" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
/branches/dd/contrib/toolchain/toolchain.mipseb32.sh |
---|
15,13 → 15,9 |
fi |
} |
if [ -z "${CROSS_PREFIX}" ] ; then |
CROSS_PREFIX="/usr/local" |
fi |
BINUTILS_VERSION="2.18" |
GCC_VERSION="4.2.2" |
BINUTILS_VERSION="2.19" |
GCC_VERSION="4.3.2" |
BINUTILS="binutils-${BINUTILS_VERSION}.tar.gz" |
GCC_CORE="gcc-core-${GCC_VERSION}.tar.bz2" |
GCC_OBJC="gcc-objc-${GCC_VERSION}.tar.bz2" |
33,7 → 29,7 |
PLATFORM="mips" |
WORKDIR=`pwd` |
TARGET="${PLATFORM}-sgi-irix5" |
PREFIX="${CROSS_PREFIX}/${PLATFORM}" |
PREFIX="/usr/local/${PLATFORM}" |
BINUTILSDIR="${WORKDIR}/binutils-${BINUTILS_VERSION}" |
GCCDIR="${WORKDIR}/gcc-${GCC_VERSION}" |
OBJDIR="${WORKDIR}/gcc-obj" |
84,21 → 80,6 |
echo ">>> Compiling and installing binutils" |
cd "${BINUTILSDIR}" |
check_error $? "Change directory failed." |
patch -p1 <<EOF |
diff -Naur binutils-2.19.orig/bfd/elfxx-mips.c binutils-2.19/bfd/elfxx-mips.c |
--- binutils-2.19.orig/bfd/elfxx-mips.c 2008-08-18 20:14:04.000000000 +0200 |
+++ binutils-2.19/bfd/elfxx-mips.c 2009-01-18 18:14:47.292011299 +0100 |
@@ -1409,7 +1409,7 @@ |
function, or 0 if we can't decide which function that is. */ |
static unsigned long |
-mips16_stub_symndx (asection *sec, const Elf_Internal_Rela *relocs, |
+mips16_stub_symndx (asection *sec __attribute__((unused)), const Elf_Internal_Rela *relocs, |
const Elf_Internal_Rela *relend) |
{ |
const Elf_Internal_Rela *rel; |
EOF |
check_error $? "Error patching binutils" |
./configure "--target=${TARGET}" "--prefix=${PREFIX}" "--program-prefix=${TARGET}-" "--disable-nls" |
check_error $? "Error configuring binutils." |
make all install |
/branches/dd/contrib/conf/arm32-gx.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
/branches/dd/contrib/conf/mips32-gx.sh |
---|
File deleted |
Property changes: |
Deleted: svn:executable |
-* |
\ No newline at end of property |
Deleted: svn:mergeinfo |
/branches/dd/contrib/conf/msim.conf |
---|
2,16 → 2,13 |
# MSIM configuration script |
# |
add dcpu cpu0 |
add dcpu cpu1 |
add dcpu mips1 |
add rwm mainmem 0x00000000 |
mainmem generic 16M |
add rwm mainmem 0x00000000 8M |
mainmem load "/dev/zero" |
add rom bootmem 0x1fc00000 |
bootmem generic 4096k |
bootmem load "image.boot" |
add rom bootmem 0x1fc00000 2048k |
bootmem load "image.boot" |
add dprinter printer 0x10000000 |
add dkeyboard keyboard 0x10000000 2 |
/branches/dd/contrib/conf/gxemul.sh |
---|
0,0 → 1,3 |
#!/bin/sh |
gxemul $@ -E testmips -C R4000 -X image.boot |
Property changes: |
Added: svn:executable |
+* |
\ No newline at end of property |
/branches/dd/contrib/conf/HelenOS.sparc64.simics |
---|
0,0 → 1,110 |
# |
# This configuration file was assembled from the bagle machine |
# configuration files as found in Simics 3.0.21. It won't probably |
# work in Simics versions prior to Simics 3.0. |
# |
# The machine simulated is SunFire server Sun Enterprise E6500. |
# |
# - modified to boot from CD-ROM |
# - framebuffer color depth set to 24bpp |
# |
script-branch { |
wait-for-variable machine_defined |
$pcibrd = (create-sunfire-pci-board mac_address = "10:10:10:10:10:14") |
$pgx64 = (create-sun-pci-pgx64) |
$gfxcon = (create-std-graphics-console) |
$keyboard = (create-sun-type5-keyboard) |
$mouse = (create-sun-type5-mouse) |
$scsi_bus = (create-std-scsi-bus) |
$system.connect slot2 $pcibrd |
$pcibrd.connect pci-slot0 $pgx64 |
$pcibrd.connect $scsi_bus |
$system.connect keyboard $keyboard |
$system.connect mouse $mouse |
$gfxcon.connect $pgx64 |
$gfxcon.connect $keyboard |
$gfxcon.connect $mouse |
} |
$save_slot2 = "yes" |
if not defined hostid {$hostid = 0x80804a6c} |
if not defined freq_mhz {$freq_mhz = 168} |
if not defined mac_address {$mac_address = "10:10:10:10:10:12"} |
if not defined disk_size {$disk_size = 2128486400} |
if not defined rtc_time {$rtc_time = "2002-06-02 13:00:00 UTC"} |
if not defined num_cpus {$num_cpus = 1} |
if not defined memory_megs {$memory_megs = 256} |
if not defined save_slot2 {$save_slot2 = "no"} |
add-directory "%simics%/targets/sunfire/images/" |
import-pci-components |
import-std-components |
import-sun-components |
import-sunfire-components |
$system = (create-sunfire-6500-backplane cpu_frequency = $freq_mhz |
hostid = $hostid |
mac_address = $mac_address |
rtc_time = $rtc_time) |
$board = 0 |
$cpus_left = $num_cpus |
$megs_left = $memory_megs |
while $cpus_left or $megs_left { |
$cpubrd[$board] = (create-sunfire-cpu-board |
num_cpus = (min $cpus_left 2) |
memory_megs = (min $megs_left 4096)) |
$system.connect ("slot" + $board) $cpubrd[$board] |
if $board == 0 { |
$system.connect central-cpu $cpubrd[$board] |
} |
$cpus_left = (max ($cpus_left - 2) 0) |
$megs_left = (max ($megs_left - 4096) 0) |
$board += 1 |
if $board == 1 {$board = 2} |
if $board == 2 and ($save_slot2 == yes) {$board = 3} |
} |
$sbusbrd = (create-sunfire-sbus-board mac_address = $mac_address) |
$scsi_bus = (create-std-scsi-bus) |
$scsi_disk = (create-std-scsi-disk scsi_id = 1 size = $disk_size) |
$scsi_cdrom = (create-std-scsi-cdrom scsi_id = 6) |
$console = (create-std-text-console) |
$system.connect slot1 $sbusbrd |
$sbusbrd.connect $scsi_bus |
$scsi_bus.connect $scsi_disk |
$scsi_bus.connect $scsi_cdrom |
$system.connect ttya $console |
$machine_defined = 1 |
instantiate-components |
$eth_comp = $sbus_fas_hme |
$eth_cnt = "" |
run-command-file "%simics%/targets/common/add-eth-link.include" |
if not defined ip_address {$ip_address = "10.10.0.6"} |
if $service_node { |
local $sn = ($service_node.get-component-object sn) |
($sn.add-host name = $host_name |
ip = $ip_address domain = network.sim |
mac = $mac_address) |
} |
default-port-forward-target $ip_address |
$cdrom_path = "/home/jermar/software/HelenOS/image.iso" |
($scsi_cdrom.get-component-object cd).insert (new-file-cdrom $cdrom_path) |
$system.set-prom-env boot-command "boot cdrom" |
$system.set-prom-env auto-boot? true |
$system.set-prom-env "output-device" "screen:r1152x900x76x24" |
/branches/dd/contrib/conf/dot.bochsrc |
---|
0,0 → 1,719 |
# You may now use double quotes around pathnames, in case |
# your pathname includes spaces. |
#======================================================================= |
# CONFIG_INTERFACE |
# |
# The configuration interface is a series of menus or dialog boxes that |
# allows you to change all the settings that control Bochs's behavior. |
# There are two choices of configuration interface: a text mode version |
# called "textconfig" and a graphical version called "wx". The text |
# mode version uses stdin/stdout and is always compiled in. The graphical |
# version is only available when you use "--with-wx" on the configure |
# command. If you do not write a config_interface line, Bochs will |
# choose a default for you. |
# |
# NOTE: if you use the "wx" configuration interface, you must also use |
# the "wx" display library. |
#======================================================================= |
config_interface: textconfig |
#config_interface: wx |
#======================================================================= |
# DISPLAY_LIBRARY |
# |
# The display library is the code that displays the Bochs VGA screen. Bochs |
# has a selection of about 10 different display library implementations for |
# different platforms. If you run configure with multiple --with-* options, |
# the display_library command lets you choose which one you want to run with. |
# If you do not write a display_library line, Bochs will choose a default for |
# you. |
# |
# The choices are: |
# x use X windows interface, cross platform |
# win32 use native win32 libraries |
# carbon use Carbon library (for MacOS X) |
# beos use native BeOS libraries |
# macintosh use MacOS pre-10 |
# amigaos use native AmigaOS libraries |
# sdl use SDL library, cross platform |
# svga use SVGALIB library for Linux, allows graphics without X11 |
# term text only, uses curses/ncurses library, cross platform |
# rfb provides an interface to AT&T's VNC viewer, cross platform |
# wx use wxWindows library, cross platform |
# nogui no display at all |
# |
# NOTE: if you use the "wx" configuration interface, you must also use |
# the "wx" display library. |
#======================================================================= |
#display_library: amigaos |
#display_library: beos |
#display_library: carbon |
#display_library: macintosh |
#display_library: nogui |
#display_library: rfb |
#display_library: sdl |
#display_library: term |
#display_library: win32 |
#display_library: wx |
display_library: x |
cpu: count=8, ips=10000000 |
#======================================================================= |
# ROMIMAGE: |
# You now need to load a ROM BIOS into F0000-FFFFF. Normally, you can |
# use a precompiled BIOS in the bios/ directory of the source tree, |
# named BIOS-bochs-latest. |
# You can also use the environment variable $BXSHARE to specify the |
# location of the BIOS. |
#======================================================================= |
romimage: file=$BXSHARE/BIOS-bochs-latest, address=0xf0000 |
#romimage: file=$BXSHARE/BIOS-bochs-8-processors, address=0xf0000 |
#romimage: file=bios/P4SMT, address=0xf0000 |
#======================================================================= |
# MEGS |
# set this to the default number of Megabytes of memory you want |
# to emulate. You may also pass the '-megs xyz' option to bochs |
# |
# The default is 32MB, most OS's won't need more than that. |
#======================================================================= |
#megs: 256 |
#megs: 128 |
#megs: 64 |
megs: 32 |
#megs: 16 |
#megs: 8 |
#======================================================================= |
# OPTROMIMAGE[1-4]: |
# You may now load up to 4 optional ROM images. Be sure to use a |
# read-only area, typically between C8000 and EFFFF. These optional |
# ROM images should not overwrite the rombios (located at |
# F0000-FFFFF) and the videobios (located at C0000-C7FFF). |
# Those ROM images will be initialized by the bios if they contain |
# the right signature (0x55AA). |
# It can also be a convenient way to upload some arbitary code/data |
# in the simulation, that can be retrieved by the boot loader |
#======================================================================= |
#optromimage1: file=optionalrom.bin, address=0xd0000 |
#optromimage2: file=optionalrom.bin, address=0xd1000 |
#optromimage3: file=optionalrom.bin, address=0xd2000 |
#optromimage4: file=optionalrom.bin, address=0xd3000 |
#======================================================================= |
# VGAROMIMAGE |
# You now need to load a VGA ROM BIOS into C0000. |
#======================================================================= |
vgaromimage: $BXSHARE/VGABIOS-lgpl-latest |
#vgaromimage: bios/VGABIOS-elpin-2.40 |
#vgaromimage: $BXSHARE/VGABIOS-elpin-2.40 |
#======================================================================= |
# FLOPPYA: |
# Point this to pathname of floppy image file or device |
# This should be of a bootable floppy(image/device) if you're |
# booting from 'a'. |
# |
# You can set the initial status of the media to 'ejected' or 'inserted'. |
# floppya: 2_88=path, status=ejected (2.88M 3.5" floppy) |
# floppya: 1_44=path, status=inserted (1.44M 3.5" floppy) |
# floppya: 1_2=path, status=ejected (1.2M 5.25" floppy) |
# floppya: 720k=path, status=inserted (720K 3.5" floppy) |
# floppya: 360k=path, status=inserted (360K 5.25" floppy) |
# floppya: 320k=path, status=inserted (320K 5.25" floppy) |
# floppya: 180k=path, status=inserted (180K 5.25" floppy) |
# floppya: 160k=path, status=inserted (160K 5.25" floppy) |
# |
# The path should be the name of a disk image file. On unix, you can use |
# a raw device name such as /dev/fd0 on Linux. On WinNT and Win2k, use |
# drive letters such as a: or b: as the path. Raw floppy access is not |
# supported on Windows 95 and 98. |
#======================================================================= |
#floppya: 1_44=image.boot, status=inserted |
#floppya: 1_44=/dev/fd0, status=inserted |
#======================================================================= |
# FLOPPYB: |
# See FLOPPYA above for syntax |
#======================================================================= |
#floppyb: 1_44=b:, status=inserted |
#floppyb: 1_44=b.img, status=inserted |
#======================================================================= |
# ATA0, ATA1, ATA2, ATA3 |
# ATA controller for hard disks and cdroms |
# |
# ata[0-3]: enabled=[0|1], ioaddr1=addr, ioaddr2=addr, irq=number |
# |
# These options enables up to 4 ata channels. For each channel |
# the two base io addresses and the irq must be specified. |
# |
# ata0 is enabled by default, with ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
# |
# Examples: |
# ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
# ata1: enabled=1, ioaddr1=0x170, ioaddr2=0x370, irq=15 |
# ata2: enabled=1, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 |
# ata3: enabled=1, ioaddr1=0x168, ioaddr2=0x360, irq=9 |
#======================================================================= |
ata0: enabled=1, ioaddr1=0x1f0, ioaddr2=0x3f0, irq=14 |
ata1: enabled=0, ioaddr1=0x170, ioaddr2=0x370, irq=15 |
ata2: enabled=0, ioaddr1=0x1e8, ioaddr2=0x3e0, irq=11 |
ata3: enabled=0, ioaddr1=0x168, ioaddr2=0x360, irq=9 |
#======================================================================= |
# ATA[0-3]-MASTER, ATA[0-3]-SLAVE |
# |
# This defines the type and characteristics of all attached ata devices: |
# type= type of attached device [disk|cdrom] |
# mode= only valid for disks [flat|concat|external|dll|sparse|vmware3] |
# mode= only valid for disks [undoable|growing|volatile] |
# path= path of the image |
# cylinders= only valid for disks |
# heads= only valid for disks |
# spt= only valid for disks |
# status= only valid for cdroms [inserted|ejected] |
# biosdetect= type of biosdetection [none|auto], only for disks on ata0 [cmos] |
# translation=type of transation of the bios, only for disks [none|lba|large|rechs|auto] |
# model= string returned by identify device command |
# journal= optional filename of the redolog for undoable and volatile disks |
# |
# Point this at a hard disk image file, cdrom iso file, or physical cdrom |
# device. To create a hard disk image, try running bximage. It will help you |
# choose the size and then suggest a line that works with it. |
# |
# In UNIX it may be possible to use a raw device as a Bochs hard disk, |
# but WE DON'T RECOMMEND IT. In Windows there is no easy way. |
# |
# In windows, the drive letter + colon notation should be used for cdroms. |
# Depending on versions of windows and drivers, you may only be able to |
# access the "first" cdrom in the system. On MacOSX, use path="drive" |
# to access the physical drive. |
# |
# The path, cylinders, heads, and spt are mandatory for type=disk |
# The path is mandatory for type=cdrom |
# |
# Default values are: |
# mode=flat, biosdetect=auto, translation=auto, model="Generic 1234" |
# |
# The biosdetect option has currently no effect on the bios |
# |
# Examples: |
# ata0-master: type=disk, mode=flat, path=10M.sample, cylinders=306, heads=4, spt=17 |
# ata0-slave: type=disk, mode=flat, path=20M.sample, cylinders=615, heads=4, spt=17 |
# ata1-master: type=disk, mode=flat, path=30M.sample, cylinders=615, heads=6, spt=17 |
# ata1-slave: type=disk, mode=flat, path=46M.sample, cylinders=940, heads=6, spt=17 |
# ata2-master: type=disk, mode=flat, path=62M.sample, cylinders=940, heads=8, spt=17 |
# ata2-slave: type=disk, mode=flat, path=112M.sample, cylinders=900, heads=15, spt=17 |
# ata3-master: type=disk, mode=flat, path=483M.sample, cylinders=1024, heads=15, spt=63 |
# ata3-slave: type=cdrom, path=iso.sample, status=inserted |
#======================================================================= |
ata0-master: type=cdrom, path="image.iso", status=inserted |
#ata0-master: type=disk, mode=flat, path="30M.sample", cylinders=615, heads=6, spt=17 |
#ata0-slave: type=cdrom, path=D:, status=inserted |
#ata0-slave: type=cdrom, path=/dev/cdrom, status=inserted |
#ata0-slave: type=cdrom, path="drive", status=inserted |
#ata0-slave: type=cdrom, path=/dev/rcd0d, status=inserted |
#======================================================================= |
# BOOT: |
# This defines your boot drive. |
# You can either boot from 'floppy', 'disk' or 'cdrom' |
# legacy 'a' and 'c' are also supported |
# Examples: |
# boot: floppy |
# boot: disk |
# boot: cdrom |
# boot: c |
# boot: a |
#======================================================================= |
boot: cdrom |
#boot: disk |
#======================================================================= |
# IPS: |
# Emulated Instructions Per Second. This is the number of IPS that bochs |
# is capable of running on your machine. Read the note in config.h |
# on how to find this. Make sure to recompile after. |
# |
# IPS is used to calibrate many time-dependent events within the bochs |
# simulation. For example, changing IPS affects the frequency of VGA |
# updates, the duration of time before a key starts to autorepeat, and |
# the measurement of BogoMips and other benchmarks. |
# |
# Examples: |
# Machine Mips |
# ________________________________________________________________ |
# 650Mhz Athlon K-7 with Linux 2.4.4/egcs-2.91.66 2 to 2.5 Mips |
# 400Mhz Pentium II with Linux 2.0.36/egcs-1.0.3 1 to 1.8 Mips |
# 166Mhz 64bit Sparc with Solaris 2.x approx 0.75 Mips |
# 200Mhz Pentium with Linux 2.x approx 0.5 Mips |
# |
#======================================================================= |
ips: 2500000 |
#======================================================================= |
# CLOCK: |
# This defines the parameters of the clock inside Bochs: |
# |
# SYNC: |
# TO BE COMPLETED (see Greg explaination in bug #536329) |
# |
# TIME0: |
# Specifies the start (boot) time of the virtual machine. Use a time |
# value as returned by the time(2) system call. If no time0 value is |
# set or if time0 equal to 1 (special case) or if time0 equal 'local', |
# the simulation will be started at the current local host time. |
# If time0 equal to 2 (special case) or if time0 equal 'utc', |
# the simulation will be started at the current utc time. |
# |
# Syntax: |
# clock: sync=[none|slowdown|realtime], time0=[timeValue|local|utc] |
# |
# Example: |
# clock: sync=none, time0=local # Now (localtime) |
# clock: sync=slowdown, time0=315529200 # Tue Jan 1 00:00:00 1980 |
# clock: sync=none, time0=631148400 # Mon Jan 1 00:00:00 1990 |
# clock: sync=realtime, time0=938581955 # Wed Sep 29 07:12:35 1999 |
# clock: sync=realtime, time0=946681200 # Sat Jan 1 00:00:00 2000 |
# clock: sync=none, time0=1 # Now (localtime) |
# clock: sync=none, time0=utc # Now (utc/gmt) |
# |
# Default value are sync=none, time0=local |
#======================================================================= |
clock: sync=none, time0=local |
#======================================================================= |
# FLOPPY_BOOTSIG_CHECK: disabled=[0|1] |
# Enables or disables the 0xaa55 signature check on boot floppies |
# Defaults to disabled=0 |
# Examples: |
# floppy_bootsig_check: disabled=0 |
# floppy_bootsig_check: disabled=1 |
#======================================================================= |
#floppy_bootsig_check: disabled=1 |
floppy_bootsig_check: disabled=1 |
#======================================================================= |
# LOG: |
# Give the path of the log file you'd like Bochs debug and misc. verbage |
# to be written to. If you really don't want it, make it /dev/null. :^( |
# |
# Examples: |
# log: ./bochs.out |
# log: /dev/tty |
#======================================================================= |
#log: /dev/null |
log: bochsout.txt |
#======================================================================= |
# LOGPREFIX: |
# This handles the format of the string prepended to each log line. |
# You may use those special tokens : |
# %t : 11 decimal digits timer tick |
# %i : 8 hexadecimal digits of cpu0 current eip |
# %e : 1 character event type ('i'nfo, 'd'ebug, 'p'anic, 'e'rror) |
# %d : 5 characters string of the device, between brackets |
# |
# Default : %t%e%d |
# Examples: |
# logprefix: %t-%e-@%i-%d |
# logprefix: %i%e%d |
#======================================================================= |
#logprefix: %t%e%d |
#======================================================================= |
# LOG CONTROLS |
# |
# Bochs now has four severity levels for event logging. |
# panic: cannot proceed. If you choose to continue after a panic, |
# don't be surprised if you get strange behavior or crashes. |
# error: something went wrong, but it is probably safe to continue the |
# simulation. |
# info: interesting or useful messages. |
# debug: messages useful only when debugging the code. This may |
# spit out thousands per second. |
# |
# For events of each level, you can choose to crash, report, or ignore. |
# TODO: allow choice based on the facility: e.g. crash on panics from |
# everything except the cdrom, and only report those. |
# |
# If you are experiencing many panics, it can be helpful to change |
# the panic action to report instead of fatal. However, be aware |
# that anything executed after a panic is uncharted territory and can |
# cause bochs to become unstable. The panic is a "graceful exit," so |
# if you disable it you may get a spectacular disaster instead. |
#======================================================================= |
panic: action=report |
error: action=report |
info: action=report |
debug: action=ignore |
#pass: action=fatal |
#======================================================================= |
# DEBUGGER_LOG: |
# Give the path of the log file you'd like Bochs to log debugger output. |
# If you really don't want it, make it /dev/null or '-'. :^( |
# |
# Examples: |
# debugger_log: ./debugger.out |
#======================================================================= |
#debugger_log: /dev/null |
#debugger_log: debugger.out |
debugger_log: - |
#======================================================================= |
# COM1: |
# This defines a serial port (UART type 16550A). You can specify a device |
# to use as com1. This can be a real serial line, or a pty. To use a pty |
# (under X/Unix), create two windows (xterms, usually). One of them will |
# run bochs, and the other will act as com1. Find out the tty the com1 |
# window using the `tty' command, and use that as the `dev' parameter. |
# Then do `sleep 1000000' in the com1 window to keep the shell from |
# messing with things, and run bochs in the other window. Serial I/O to |
# com1 (port 0x3f8) will all go to the other window. |
#======================================================================= |
#com1: enabled=1, dev=/dev/ttyp9 |
#======================================================================= |
# PARPORT1: |
# This defines a parallel (printer) port. When turned on and an output file is |
# defined the emulated printer port sends characters printed by the guest OS |
# into the output file. On some platforms a device filename can be used to |
# send the data to the real parallel port (e.g. "/dev/lp0" on Linux, "lpt1" on |
# win32 platforms). |
# |
# Examples: |
# parport1: enabled=1, file="parport.out" |
# parport1: enabled=1, file="/dev/lp0" |
# parport1: enabled=0 |
#======================================================================= |
parport1: enabled=1, file="parport.out" |
#======================================================================= |
# SB16: |
# This defines the SB16 sound emulation. It can have several of the |
# following properties. |
# All properties are in the format sb16: property=value |
# midi: The filename is where the midi data is sent. This can be a |
# device or just a file if you want to record the midi data. |
# midimode: |
# 0=no data |
# 1=output to device (system dependent. midi denotes the device driver) |
# 2=SMF file output, including headers |
# 3=output the midi data stream to the file (no midi headers and no |
# delta times, just command and data bytes) |
# wave: This is the device/file where wave output is stored |
# wavemode: |
# 0=no data |
# 1=output to device (system dependent. wave denotes the device driver) |
# 2=VOC file output, incl. headers |
# 3=output the raw wave stream to the file |
# log: The file to write the sb16 emulator messages to. |
# loglevel: |
# 0=no log |
# 1=only midi program and bank changes |
# 2=severe errors |
# 3=all errors |
# 4=all errors plus all port accesses |
# 5=all errors and port accesses plus a lot of extra info |
# dmatimer: |
# microseconds per second for a DMA cycle. Make it smaller to fix |
# non-continous sound. 750000 is usually a good value. This needs a |
# reasonably correct setting for IPS. |
# |
# For an example look at the next line: |
#======================================================================= |
#sb16: midimode=1, midi=/dev/midi00, wavemode=1, wave=/dev/dsp, loglevel=2, log=sb16.log, dmatimer=600000 |
#======================================================================= |
# VGA_UPDATE_INTERVAL: |
# Video memory is scanned for updates and screen updated every so many |
# virtual seconds. The default is 300000, about 3Hz. This is generally |
# plenty. Keep in mind that you must tweak the 'ips:' directive |
# to be as close to the number of emulated instructions-per-second |
# your workstation can do, for this to be accurate. |
# |
# Examples: |
# vga_update_interval: 250000 |
#======================================================================= |
vga_update_interval: 300000 |
# using for Winstone '98 tests |
#vga_update_interval: 100000 |
#======================================================================= |
# KEYBOARD_SERIAL_DELAY: |
# Approximate time in microseconds that it takes one character to |
# be transfered from the keyboard to controller over the serial path. |
# Examples: |
# keyboard_serial_delay: 200 |
#======================================================================= |
keyboard_serial_delay: 250 |
#======================================================================= |
# KEYBOARD_PASTE_DELAY: |
# Approximate time in microseconds between attempts to paste |
# characters to the keyboard controller. This leaves time for the |
# guest os to deal with the flow of characters. The ideal setting |
# depends on how your operating system processes characters. The |
# default of 100000 usec (.1 seconds) was chosen because it works |
# consistently in Windows. |
# |
# If your OS is losing characters during a paste, increase the paste |
# delay until it stops losing characters. |
# |
# Examples: |
# keyboard_paste_delay: 100000 |
#======================================================================= |
keyboard_paste_delay: 100000 |
#======================================================================= |
# FLOPPY_COMMAND_DELAY: |
# Time in microseconds to wait before completing some floppy commands |
# such as read/write/seek/etc, which normally have a delay associated. |
# I had this hardwired to 50,000 before. |
# |
# Examples: |
# floppy_command_delay: 50000 |
#======================================================================= |
floppy_command_delay: 500 |
#======================================================================= |
# MOUSE: |
# This option prevents Bochs from creating mouse "events" unless a mouse |
# is enabled. The hardware emulation itself is not disabled by this. |
# You can turn the mouse on by setting enabled to 1, or turn it off by |
# setting enabled to 0. Unless you have a particular reason for enabling |
# the mouse by default, it is recommended that you leave it off. |
# You can also toggle the mouse usage at runtime (middle mouse button on |
# X11 and SDL, F12 on Win32). |
# |
# Examples: |
# mouse: enabled=1 |
# mouse: enabled=0 |
#======================================================================= |
mouse: enabled=0 |
#======================================================================= |
# private_colormap: Request that the GUI create and use it's own |
# non-shared colormap. This colormap will be used |
# when in the bochs window. If not enabled, a |
# shared colormap scheme may be used. Not implemented |
# on all GUI's. |
# |
# Examples: |
# private_colormap: enabled=1 |
# private_colormap: enabled=0 |
#======================================================================= |
private_colormap: enabled=0 |
#======================================================================= |
# fullscreen: ONLY IMPLEMENTED ON AMIGA |
# Request that Bochs occupy the entire screen instead of a |
# window. |
# |
# Examples: |
# fullscreen: enabled=0 |
# fullscreen: enabled=1 |
#======================================================================= |
#fullscreen: enabled=0 |
#screenmode: name="sample" |
#======================================================================= |
# ne2k: NE2000 compatible ethernet adapter |
# |
# Examples: |
# ne2k: ioaddr=IOADDR, irq=IRQ, mac=MACADDR, ethmod=MODULE, ethdev=DEVICE, script=SCRIPT |
# |
# ioaddr, irq: You probably won't need to change ioaddr and irq, unless there |
# are IRQ conflicts. |
# |
# mac: The MAC address MUST NOT match the address of any machine on the net. |
# Also, the first byte must be an even number (bit 0 set means a multicast |
# address), and you cannot use ff:ff:ff:ff:ff:ff because that's the broadcast |
# address. For the ethertap module, you must use fe:fd:00:00:00:01. There may |
# be other restrictions too. To be safe, just use the b0:c4... address. |
# |
# ethdev: The ethdev value is the name of the network interface on your host |
# platform. On UNIX machines, you can get the name by running ifconfig. On |
# Windows machines, you must run niclist to get the name of the ethdev. |
# Niclist source code is in misc/niclist.c and it is included in Windows |
# binary releases. |
# |
# script: The script value is optionnal, and is the name of a script that |
# is executed after bochs initialize the network interface. You can use |
# this script to configure this network interface, or enable masquerading. |
# This is mainly useful for the tun/tap devices that only exist during |
# Bochs execution. The network interface name is supplied to the script |
# as first parameter |
#======================================================================= |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=fbsd, ethdev=en0 #macosx |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:00, ethmod=fbsd, ethdev=xl0 |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:00, ethmod=linux, ethdev=eth0 |
# ne2k: ioaddr=0x240, irq=9, mac=b0:c4:20:00:00:01, ethmod=win32, ethdev=MYCARD |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=tap, ethdev=tap0 |
# ne2k: ioaddr=0x240, irq=9, mac=fe:fd:00:00:00:01, ethmod=tuntap, ethdev=tun0, script=./tunconfig |
#======================================================================= |
# KEYBOARD_MAPPING: |
# This enables a remap of a physical localized keyboard to a |
# virtualized us keyboard, as the PC architecture expects. |
# If enabled, the keymap file must be specified. |
# |
# Examples: |
# keyboard_mapping: enabled=1, map=gui/keymaps/x11-pc-de.map |
#======================================================================= |
keyboard_mapping: enabled=0, map= |
#======================================================================= |
# KEYBOARD_TYPE: |
# Type of keyboard return by a "identify keyboard" command to the |
# keyboard controler. It must be one of "xt", "at" or "mf". |
# Defaults to "mf". It should be ok for almost everybody. A known |
# exception is french macs, that do have a "at"-like keyboard. |
# |
# Examples: |
# keyboard_type: mf |
#======================================================================= |
#keyboard_type: mf |
#======================================================================= |
# USER_SHORTCUT: |
# This defines the keyboard shortcut to be sent when you press the "user" |
# button in the headerbar. The shortcut string can be a combination of |
# these key names: "alt", "bksp", "ctrl", "del", "esc", "f1", "f4", "tab" |
# and "win". Up to 3 keys can be pressed at a time. |
# |
# Example: |
# user_shortcut: keys=ctrlaltdel |
#======================================================================= |
#user_shortcut: keys=ctrlaltdel |
#======================================================================= |
# other stuff |
#======================================================================= |
#magic_break: enabled=1 |
#cmosimage: cmos.img |
#load32bitOSImage: os=nullkernel, path=../kernel.img, iolog=../vga_io.log |
#load32bitOSImage: os=linux, path=../linux.img, iolog=../vga_io.log, initrd=../initrd.img |
#i440fxsupport: enabled=1 |
usb1: enabled=1, ioaddr=0xFF80, irq=10 |
#text_snapshot_check: enable |
#======================================================================= |
# for Macintosh, use the style of pathnames in the following |
# examples. |
# |
# vgaromimage: :bios:VGABIOS-elpin-2.40 |
# romimage: file=:bios:BIOS-bochs-latest, address=0xf0000 |
# floppya: 1_44=[fd:], status=inserted |
#======================================================================= |
#======================================================================= |
# |
# The following directives are DEPRECATED |
# Please convert them to the new syntax or remove them |
# |
#======================================================================= |
#======================================================================= |
# |
# The DISKC option is deprecated. Use ATA* options instead. |
# |
# DISKC: file=, cyl=, heads=, spt= |
# Point this at a hard disk image file. To create |
# a hard disk image, try running bximage. It will help you choose the |
# size and then suggest a diskc line that works with it. |
# |
# In UNIX it may be possible to use a raw device as a Bochs hard disk, |
# but WE DON'T RECOMMEND IT. In Windows there is no easy way. |
# |
# Examples: |
# diskc: file=10M.sample, cyl=306, heads=4, spt=17 |
# diskc: file=20M.sample, cyl=615, heads=4, spt=17 |
# diskc: file=30M.sample, cyl=615, heads=6, spt=17 |
# diskc: file=46M.sample, cyl=940, heads=6, spt=17 |
# diskc: file=62M.sample, cyl=940, heads=8, spt=17 |
# diskc: file=112M.sample, cyl=900, heads=15, spt=17 |
# diskc: file=483M.sample, cyl=1024, heads=15, spt=63 |
#======================================================================= |
#diskc: file="30M.sample", cyl=615, heads=6, spt=17 |
#======================================================================= |
# |
# The DISKD option is deprecated. Use ATA* options instead. |
# |
# DISKD: |
# See DISKC above for syntax |
# |
# NOTE: diskd and cdromd must not be used together! |
#======================================================================= |
#diskd: file="diskd.img", cyl=615, heads=6, spt=17 |
#======================================================================= |
# |
# The CDROMD option is deprecated. Use ATA* options instead. |
# |
# CDROMD: |
# |
# cdromd: dev=/dev/cdrom, status=inserted |
# cdromd: dev=/dev/cdrom, status=ejected |
# cdromd: dev=e:, status=ejected |
# |
# In windows, the drive letter + colon notation should be used for cdroms. |
# Depending on versions of windows and drivers, you may only be able to |
# access the "first" cdrom in the system. On MacOSX, use path="drive" |
# to access the physical drive. |
# |
# NOTE: diskd and cdromd must not be used together! |
#======================================================================= |
#cdromd: dev=D:, status=inserted |
#cdromd: dev=/dev/cdrom, status=inserted |
#cdromd: dev="drive", status=inserted |
#======================================================================= |
# |
# The TIME0 directive is DEPRECATED. Use the CLOCK directive instead |
# |
# TIME0: |
# Specifies the start (boot) time of the virtual machine. Use a time |
# value as returned by the time(2) system call. If no time0 value is |
# set or if time0 equal to 1 (special case), the simulation will be |
# started at the current time of the host. |
# |
# Examples: |
# time0: 1 # Now |
# time0: 315529200 # Tue Jan 1 00:00:00 1980 |
# time0: 631148400 # Mon Jan 1 00:00:00 1990 |
# time0: 938581955 # Wed Sep 29 07:12:35 1999 |
# time0: 946681200 # Sat Jan 1 00:00:00 2000 |
#======================================================================= |
#time0: 938581955 |
#======================================================================= |
# |
# The PIT directive is DEPRECATED. Use the CLOCK directive instead |
# |
# PIT: |
# The PIT is the programmable interval timer. It has an option that tries to |
# keep the PIT in sync with real time. This feature is still experimental, |
# but it may be useful if you want to prevent Bochs from running too fast, for |
# example a DOS video game. Be aware that with the realtime pit option, your |
# simulation will not be repeatable; this can a problem if you are debugging. |
#======================================================================= |
#pit: realtime=1 |
#======================================================================= |
# NEWHARDDRIVESUPPORT: enabled=[0|1] |
# The old harddrive code is not maintened any more. |
# Default value is enabled=1 |
#======================================================================= |
#newharddrivesupport: enabled=1 |
/branches/dd/contrib/conf/HelenOS.amd64.simics |
---|
0,0 → 1,57 |
# |
# Simics 3.0 AMD64 configuration |
# |
$num_cpus = 2 |
$cpu_class = "x86-hammer" |
$freq_mhz = 50 |
add-directory "%simics%/targets/x86-440bx/images" |
import-isa-components |
import-pci-components |
import-std-components |
import-x86-components |
$system = (create-x86-apic-system memory_megs = 256 |
rtc_time = "2006-03-12 10:00:00 UTC" |
break_on_reboot = 1 |
bios = "rombios-2.65.2.3") |
$count = 0 |
$create_command = ("create-" + $cpu_class + "-cpu") |
while $count < $num_cpus { |
$cpu[$count] = ($create_command cpu_frequency = $freq_mhz) |
$system.connect ("cpu" + $count) $cpu[$count] |
$count += 1 |
} |
$nb = (create-north-bridge-443bx-agp) |
$vga = (create-agp-voodoo3) |
$nb.connect agp-slot0 $vga |
$sb = (create-south-bridge-piix4) |
$sio = (create-std-super-io) |
$cdrom = (create-std-ide-cdrom) |
$console = (create-std-graphics-console) |
$console.connect mouse $sio mse-console |
$console.connect keyboard $sio kbd-console |
$console.connect $vga |
$system.connect chipset $nb |
$system.connect interrupt $sb |
$system.connect reset $sio |
$nb.connect pci-slot7 $sb |
$sb.connect $sio |
$sb.connect ide0-slave $cdrom |
instantiate-components |
run-python-file "%simics%/home/scripts/cdrom_bootloader.py" |
@install_cdrom_bootloader((conf.cpu0,)) |
new-file-cdrom "image.iso" image |
cd0.insert image |
/branches/dd/contrib/conf/simics.conf |
---|
0,0 → 1,25 |
# Test machine features |
# - Standard PC system |
# - 256 Mb memory |
# - 40 MHz processor(s) |
# - AM79C960 NIC (ISA Lance) |
# - Voodoo3 PCI graphics device |
@num_processors = 2 |
#@num_processors = 1 |
@if not "cpu_class" in dir(): cpu_class = "x86-hammer" |
@if not "clock_freq_mhz" in dir(): clock_freq_mhz = 40 |
@if not "memory_megs" in dir(): memory_megs = 256 |
@if not "cdrom_image" in dir(): cdrom_image = "image.iso" |
@if not "use_voodoo3_pci" in dir(): use_voodoo3_pci = 1 |
@if not "use_voodoo3_agp" in dir(): use_voodoo3_agp = 0 |
run-command-file ../x86-test-machine/pc-common.simics |
run-python-file ../scripts/cdrom_bootloader.py |
@install_cdrom_bootloader((conf.cpu0,)) |
@if cdrom_image != None: |
eval_cli_line("new-file-cdrom %s image" % cdrom_image) |
eval_cli_line("cd0.insert image") |
/branches/dd/contrib/conf/HelenOS.ppc32.simics |
---|
0,0 → 1,32 |
# |
# Simics 3.0 PPC32 simple configuration |
# |
$cpu_class = "ppc750" |
$freq_mhz = 50 |
$image = "image.boot" |
$image_offset = -0x7a000000 |
add-directory "%simics%/targets/ppc64-simple/images" |
import-std-components |
import-ppc-simple-components |
$system = (create-ppc-simple cpu_class = $cpu_class |
cpu_frequency = $freq_mhz |
memory_megs = 256) |
$cpu = ($system.get-component-object "cpu") |
$system.connect uart0 (create-std-text-console) |
instantiate-components |
$start = (load-binary $image $image_offset) |
$cpu->msr = ($cpu->msr | (1 << 13) | (1 << 5) | (1 << 4)) |
$cpu.set-pc $start - $image_offset |
@itlb = conf.cpu0.itlb |
@itlb[0] = [[0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] |
@conf.cpu0.itlb = itlb |
/branches/dd/contrib/conf/spmips.conf |
---|
0,0 → 1,263 |
OBJECT cpu0 TYPE mips-4kc { |
freq-mhz: 10 |
queue: cpu0 |
physical-memory: phys-mem0 |
} |
OBJECT phys-mem0 TYPE memory-space { |
map: ((0x18000020, pic0, 0, 0x20, 1), |
(0x18000021, pic0, 0, 0x21, 1), |
(0x180000a0, pic0, 0, 0xa0, 1), |
(0x180000a1, pic0, 0, 0xa1, 1), |
(0x180004d0, pic0, 0, 0x4d0, 1), |
(0x180004d1, pic0, 0, 0x4d1, 1), |
(0x18000070, rtc0, 0, 0, 1), |
(0x18000071, rtc0, 0, 1, 1), |
(0x180003f8, tty0, 0, 0, 1), |
(0x180003f9, tty0, 0, 1, 1), |
(0x180003fa, tty0, 0, 2, 1), |
(0x180003fb, tty0, 0, 3, 1), |
(0x180003fc, tty0, 0, 4, 1), |
(0x180003fd, tty0, 0, 5, 1), |
(0x180003fe, tty0, 0, 6, 1), |
(0x180003ff, tty0, 0, 7, 1), |
(0x1c000000, hfs0, 0, 0, 16), |
(0x01000000, initmem0, 0, 0, 0x100000)) |
} |
OBJECT cbus-space TYPE memory-space { |
map: ((0x1f000000, malta0, 0, 0, 0xc00000), |
(0x1fc00000, rom0, 0, 0, 0x400000)) |
} |
OBJECT memory0 TYPE ram { |
image: memory0-image |
} |
OBJECT memory0-image TYPE image { |
queue: cpu0 |
size: 0x08000000 |
} |
OBJECT initmem0 TYPE ram { |
image: initmem0-image |
} |
OBJECT initmem0-image TYPE image { |
queue: cpu0 |
size: 0x100000 |
files: (("../../../uspace/init/init", "ro", 0,0)) |
} |
OBJECT rom0 TYPE rom { |
image: rom0-image |
} |
OBJECT rom0-image TYPE image { |
queue: cpu0 |
size: 0x00400000 |
} |
OBJECT tty0 TYPE NS16550 { |
irq-dev: pic0 |
irq-level: 4 |
queue: cpu0 |
console: con0 |
recorder: rec0 |
} |
OBJECT pic0 TYPE i8259x2 { |
queue: cpu0 |
irq-dev: gt64120-0 |
# It seems like Linux expects the master 8259 to have VBA 0. |
# Maybe that would be set up by YAMON? |
vba: (0, 1) |
} |
OBJECT con0 TYPE xterm-console { |
title: "mips32-test-machine" |
bg-color: "black" |
fg-color: "green" |
queue: cpu0 |
device: tty0 |
output-timeout: 120 |
} |
OBJECT rtc0 TYPE DS12887 { |
irq-dev: pic0 |
irq-level: 8 |
queue: cpu0 |
} |
OBJECT malta0 TYPE malta { |
console: display0 |
} |
OBJECT display0 TYPE xterm-console { |
title: "MALTA Display" |
bg-color: "black" |
fg-color: "red" |
width: 8 |
height: 1 |
scrollbar: 0 |
x11-font: "-*-*-*-r-*-*-*-240-*-*-m-*-*-*" |
win32-font: "Lucida Console:Bold:48" |
queue: cpu0 |
output-timeout: 120 |
} |
# PCI buses |
OBJECT pci-bus0 TYPE pci-bus { |
queue: cpu0 |
bridge: gt64120-0-pci-0-0 |
interrupt: gt64120-0-pci-0-0 |
conf-space: pci-bus0-conf-space |
memory-space: pci-bus0-memory-space |
io-space: pci-bus0-io-space |
pci-devices: ((0, 0, gt64120-0-pci-0-0), |
(0, 1, gt64120-0-pci-0-1)) |
} |
OBJECT pci-bus0-conf-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1-conf-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus0-memory-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1 TYPE pci-bus { |
queue: cpu0 |
bridge: gt64120-0-pci-1-0 |
interrupt: gt64120-0-pci-1-0 |
conf-space: pci-bus1-conf-space |
memory-space: pci-bus1-memory-space |
io-space: pci-bus1-io-space |
pci-devices: ((0, 0, gt64120-0-pci-1-0), |
(0, 1, gt64120-0-pci-1-1)) |
} |
OBJECT pci-bus1-memory-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus0-io-space TYPE memory-space { |
queue: cpu0 |
} |
OBJECT pci-bus1-io-space TYPE memory-space { |
queue: cpu0 |
} |
# GT64120 chipset |
OBJECT gt64120-0 TYPE GT64120 { |
queue: cpu0 |
cpu-mem: phys-mem0 |
pci-0-0: gt64120-0-pci-0-0 |
pci-0-1: gt64120-0-pci-0-1 |
pci-1-0: gt64120-0-pci-1-0 |
pci-1-1: gt64120-0-pci-1-1 |
scs0: memory0 |
cs3: cbus-space |
bootcs: cbus-space |
pci-0-conf: pci-bus0-conf-space |
pci-0-io: pci-bus0-io-space |
pci-0-memory: pci-bus0-memory-space |
pci-1-conf: pci-bus1-conf-space |
pci-1-io: pci-bus1-io-space |
pci-1-memory: pci-bus1-memory-space |
irq-dev: cpu0 |
irq-level: 2 |
# Little endian |
cpu_interface_configuration: 0x00041000 |
# Map 128MB RAM. |
scs10-high-decode-address: 0x40 |
scs0-low-decode-address: 0x0 |
scs0-high-decode-address: 0x7f |
# Map the internal registers at 0x1be00000. |
internal-space-decode: 0xdf |
# Disable host-PCI mappings |
pci-0-io-high-decode-address: 0 |
pci-0-io-low-decode-address: 1 |
pci-0-io-remap: 1 |
pci-0-memory-0-high-decode-address: 0 |
pci-0-memory-0-low-decode-address: 1 |
pci-0-memory-0-remap: 1 |
pci-0-memory-1-high-decode-address: 0 |
pci-0-memory-1-low-decode-address: 1 |
pci-0-memory-1-remap: 1 |
pci-1-io-high-decode-address: 0 |
pci-1-io-low-decode-address: 1 |
pci-1-io-remap: 1 |
pci-1-memory-0-high-decode-address: 0 |
pci-1-memory-0-low-decode-address: 1 |
pci-1-memory-0-remap: 1 |
pci-1-memory-1-high-decode-address: 0 |
pci-1-memory-1-low-decode-address: 1 |
pci-1-memory-1-remap: 1 |
# Disable PCI-host mappings |
pci-0-base-address-registers-enable: 0x1ff |
pci-1-base-address-registers-enable: 0x1ff |
} |
OBJECT gt64120-0-pci-0-0 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 0 |
function-num: 0 |
pci-bus: pci-bus0 |
} |
OBJECT gt64120-0-pci-0-1 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 0 |
function-num: 1 |
pci-bus: pci-bus0 |
} |
OBJECT gt64120-0-pci-1-0 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 1 |
function-num: 0 |
pci-bus: pci-bus1 |
} |
OBJECT gt64120-0-pci-1-1 TYPE GT64120-pci { |
queue: cpu0 |
gt64120: gt64120-0 |
bridge-num: 1 |
function-num: 1 |
pci-bus: pci-bus1 |
} |
# Various |
OBJECT rec0 TYPE recorder { |
} |
OBJECT hfs0 TYPE hostfs { |
} |
OBJECT sim TYPE sim { |
handle-outside-memory: 1 |
} |
/branches/dd/contrib/conf/bootindy |
---|
0,0 → 1,2 |
Without this the indy will not boot |
echo 1 > /proc/sys/net/ipv4/ip_no_pmtu_disc |
/branches/dd/contrib/conf/SPMIPS.simics |
---|
0,0 → 1,14 |
run-python-file ../scripts/extrapath.py |
add-directory ../../import/mips |
read-configuration spmips.conf |
set-pc (cpu0.load-binary ../../../SPARTAN/kernel.bin) |
# Setup uart to use 8 bits |
@conf.tty0.lcr = 0xf; |
# Set date |
rtc0.set-date-time 2001 01 01 01 01 01 |
@century = 20 |
@ignore=SIM_set_attribute_idx(conf.rtc0, "nvram", 0x32, century) |
/branches/dd/contrib/conf/vmware.conf |
---|
0,0 → 1,15 |
#!/opt/vmware/bin/vmware |
config.version = "8" |
virtualHW.version = "4" |
scsi0.present = "FALSE" |
memsize = "96" |
ide0:0.present = "FALSE" |
ide1:0.present = "FALSE" |
floppy0.startConnected = "TRUE" |
floppy0.fileType = "file" |
floppy0.fileName = "image.bin" |
sound.present = "FALSE" |
displayName = "HelenOS" |
guestOS = "other" |
nvram = "HelenOS.nvram" |
isolation.tools.hgfs.disable = "TRUE" |
/branches/dd/Makefile |
---|
29,28 → 29,119 |
## Include configuration |
# |
.PHONY: all config distclean clean cscope |
-include Makefile.config |
all: Makefile.config config.h config.defs |
$(MAKE) -C kernel |
$(MAKE) -C uspace |
$(MAKE) -C boot |
## Setup platform configuration |
# |
Makefile.config config.h config.defs: HelenOS.config |
tools/config.py HelenOS.config default |
ifeq ($(PLATFORM),amd64) |
KARCH = amd64 |
MACHINE = opteron |
UARCH = amd64 |
BARCH = amd64 |
endif |
ifeq ($(PLATFORM),arm32) |
KARCH = arm32 |
UARCH = arm32 |
BARCH = arm32 |
endif |
ifeq ($(PLATFORM),ia32) |
KARCH = ia32 |
UARCH = ia32 |
BARCH = ia32 |
endif |
ifeq ($(PLATFORM),ia64) |
KARCH = ia64 |
UARCH = ia64 |
BARCH = ia64 |
endif |
ifeq ($(PLATFORM),mips32) |
KARCH = mips32 |
BARCH = mips32 |
ifeq ($(MACHINE),msim) |
UARCH = mips32 |
IMAGE = binary |
endif |
ifeq ($(MACHINE),simics) |
UARCH = mips32 |
IMAGE = ecoff |
endif |
ifeq ($(MACHINE),bgxemul) |
UARCH = mips32eb |
IMAGE = ecoff |
endif |
ifeq ($(MACHINE),lgxemul) |
UARCH = mips32 |
IMAGE = ecoff |
endif |
ifeq ($(MACHINE),indy) |
UARCH = mips32eb |
IMAGE = ecoff |
endif |
endif |
ifeq ($(PLATFORM),ppc32) |
KARCH = ppc32 |
UARCH = ppc32 |
BARCH = ppc32 |
endif |
ifeq ($(PLATFORM),ppc64) |
KARCH = ppc64 |
UARCH = ppc64 |
BARCH = ppc64 |
endif |
ifeq ($(PLATFORM),sparc64) |
KARCH = sparc64 |
UARCH = sparc64 |
BARCH = sparc64 |
endif |
ifeq ($(PLATFORM),ia32xen) |
KARCH = ia32xen |
UARCH = ia32 |
BARCH = ia32xen |
endif |
.PHONY: all build config distclean clean |
all: |
tools/config.py HelenOS.config default $(PLATFORM) $(COMPILER) $(CONFIG_DEBUG) |
$(MAKE) -C . build |
build: |
ifneq ($(MACHINE),) |
$(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) MACHINE=$(MACHINE) |
else |
$(MAKE) -C kernel ARCH=$(KARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) |
endif |
$(MAKE) -C uspace ARCH=$(UARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) |
ifneq ($(IMAGE),) |
$(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) IMAGE=$(IMAGE) |
else |
$(MAKE) -C boot ARCH=$(BARCH) COMPILER=$(COMPILER) CONFIG_DEBUG=$(CONFIG_DEBUG) |
endif |
config: |
tools/config.py HelenOS.config |
distclean: clean |
rm -f Makefile.config config.h config.defs tools/*.pyc |
distclean: |
-$(MAKE) -C kernel distclean |
-$(MAKE) -C uspace distclean |
-$(MAKE) -C boot distclean |
-rm Makefile.config |
clean: |
-$(MAKE) -C kernel clean |
-$(MAKE) -C uspace clean |
-$(MAKE) -C boot clean |
cscope: |
find kernel boot uspace -regex '^.*\.[chsS]$$' -print > srclist |
rm -f cscope.out |
cscope -bi srclist |