From daf07b59461da5aa63eaa662b3c022a079983590 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Wed, 18 May 2011 22:35:45 +0530 Subject: [PATCH 01/76] Initial port of MIPS architecture. Completely untested. Shouldn't be merged to master. Signed-off-by: Himanshu Chauhan --- ports/mips/Doxyfile | 1161 +++++++++++++++++++++++++++++++++ ports/mips/Makefile | 107 +++ ports/mips/atomport-asm.s | 97 +++ ports/mips/atomport-entry.s | 230 +++++++ ports/mips/atomport-private.h | 148 +++++ ports/mips/atomport-tests.h | 48 ++ ports/mips/atomport-types.h | 42 ++ ports/mips/atomport.c | 75 +++ ports/mips/atomport.h | 53 ++ ports/mips/tests-main.c | 297 +++++++++ 10 files changed, 2258 insertions(+) create mode 100644 ports/mips/Doxyfile create mode 100644 ports/mips/Makefile create mode 100644 ports/mips/atomport-asm.s create mode 100644 ports/mips/atomport-entry.s create mode 100644 ports/mips/atomport-private.h create mode 100644 ports/mips/atomport-tests.h create mode 100644 ports/mips/atomport-types.h create mode 100644 ports/mips/atomport.c create mode 100644 ports/mips/atomport.h create mode 100644 ports/mips/tests-main.c diff --git a/ports/mips/Doxyfile b/ports/mips/Doxyfile new file mode 100644 index 0000000..e6f6571 --- /dev/null +++ b/ports/mips/Doxyfile @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = atomthreads + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen-avr + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ports/mips/Makefile b/ports/mips/Makefile new file mode 100644 index 0000000..016c290 --- /dev/null +++ b/ports/mips/Makefile @@ -0,0 +1,107 @@ +############ +# Settings # +############ + +# Build all test applications: +# make +# +# Program a test application using UISP (appname => test app e.g. sems1): +# make program app=appname + +# Location of build tools and atomthreads sources +KERNEL_DIR=../../kernel +TESTS_DIR=../../tests +CC=mips-linux-gnu-gcc +OBJCOPY=mips-linux-gnu-objcopy + +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Directory for built objects +BUILD_DIR=build + +# Port/application object files +APP_OBJECTS = atomport.o test-main.o +APP_ASM_OBJECTS = atomport-asm.o atomport-entry.o + +# Kernel object files +KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o + +# Collection of built objects (excluding test applications) +ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) +BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) + +# Test object files (dealt with separately as only one per application build) +TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c))) + +# Target application filenames (.elf and .hex) for each test object +TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) +TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS)) + +# Search build/output directory for dependencies +vpath %.o ./$(BUILD_DIR) +vpath %.elf ./$(BUILD_DIR) +vpath %.hex ./$(BUILD_DIR) + +# GCC flags +CFLAGS=-g -Wall -Werror + +# Enable stack-checking (disable if not required) +ifeq ($(STACK_CHECK),true) +CFLAGS += -DATOM_STACK_CHECKING +endif + + +################# +# Build targets # +################# + +# All tests +all: $(BUILD_DIR) $(TEST_HEXS) Makefile + +# Make build/output directory +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +# Test HEX files (one application build for each test) +$(TEST_HEXS): %.hex: %.elf + @echo Building $@ + $(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + +# Test ELF files (one application build for each test) +$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS) + $(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map + +# Kernel objects builder +$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c + $(CC) -c $(CFLAGS) -I. $< -o $(BUILD_DIR)/$(notdir $@) + +# Test objects builder +$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c + $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application C objects builder +$(APP_OBJECTS): %.o: ./%.c + $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application asm objects builder +$(APP_ASM_OBJECTS): %.o: ./%.s + $(CC) -c $(CFLAGS) -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# .lst file builder +%.lst: %.c + $(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + +# Clean +clean: + rm -f *.o *.elf *.map *.hex *.bin *.lst + rm -rf doxygen-kernel + rm -rf doxygen-avr + rm -rf build + +doxygen: + doxygen $(KERNEL_DIR)/Doxyfile + doxygen ./Doxyfile diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s new file mode 100644 index 0000000..b9c9cd3 --- /dev/null +++ b/ports/mips/atomport-asm.s @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + +.section .text + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +.globl archContextSwitch +archContextSwitch: + lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + lw k1, 0(a1) + + sw s0, (s0_IDX * 4)(a0) + sw s1, (s1_IDX * 4)(a0) + sw s2, (s2_IDX * 4)(a0) + sw s3, (s3_IDX * 4)(a0) + sw s4, (s4_IDX * 4)(a0) + sw s5, (s5_IDX * 4)(a0) + sw s6, (s6_IDX * 4)(a0) + sw s7, (s7_IDX * 4)(a0) + sw s8, (s8_IDX * 4)(a0) + sw sp, (sp_IDX * 4)(a0) + sw gp, (gp_IDX * 4)(a0) + + lw s0, (s0_IDX * 4)(a1) + lw s1, (s1_IDX * 4)(a1) + lw s2, (s2_IDX * 4)(a1) + lw s3, (s3_IDX * 4)(a1) + lw s4, (s4_IDX * 4)(a1) + lw s5, (s5_IDX * 4)(a1) + lw s6, (s6_IDX * 4)(a1) + lw s7, (s7_IDX * 4)(a1) + lw s8, (s8_IDX * 4)(a1) + lw sp, (sp_IDX * 4)(a1) + lw gp, (gp_IDX * 4)(a1) + + j ra + nop + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +.globl archFirstThreadRestore +archFirstThreadRestore: + move k0, a0 /* save the copy of tcb pointer in k0 */ + lw k1, 0(k0) /* Assume that sp_save_ptr is always at base of ATOM_TCB */ + lw a0, (a0_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop + eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s new file mode 100644 index 0000000..c746923 --- /dev/null +++ b/ports/mips/atomport-entry.s @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2010 Himanshu Chauhan. + * All rights reserved. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * @file start.S + * @version 0.1 + * @author Himanshu Chauhan (hschauhan@nulltrace.org) + * @brief 24Kc startup file. + */ + +#include "atomport-private.h" + +.extern _stack_start +.section .start.text,"ax",@progbits + +EXCEPTION_VECTOR(_tlbmiss, 0x00, _handle_tlbmiss) +EXCEPTION_VECTOR(_cache_error, 0x100, _handle_cache_error) +EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception) +/* FIXME: We don't need this when in EIC mode. */ +EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt) + +LEAF(_start) + mtc0 ZERO, CP0_CONTEXT + nop + nop + nop + + /* globally disable interrupts until we are prepared. */ + disable_global_interrupts + + /* clear CPU timer counters. We don't want surprises. */ + mtc0 ZERO, CP0_COMPARE + mtc0 ZERO, CP0_COUNT + + /* Read number of tlb entries from config register */ + bal num_tlb_entries + nop + + /* initialize tlb */ + bal tlb_init + move A0, V0 + + la SP, _stack_start /* setup the stack (bss segment) */ + la T0, cpu_init + j T0 /* Call the C- code now */ + nop + +1: b 1b /* we should not come here whatsoever */ +END(_start) + +/* + * Read config 1 register and return the number + * of TLB entries in this CPU. + */ +LEAF(num_tlb_entries) + mfc0 A1, CP0_CONFIG1 + nop + nop + nop + srl V0, A1, 25 + and V0, V0, 0x3F + jr RA + nop +END(num_tlb_entries) + +/** + * tlb_init + * Initialize the TLB to a power-up state, guaranteeing that all entries + * are unique and invalid. + * Arguments: + * a0 = Maximum TLB index (from MMUSize field of C0_Config1) + * Returns: + * No value + * Restrictions: + * This routine must be called in unmapped space + * Algorithm: + * va = kseg0_base; + * for (entry = max_TLB_index ; entry >= 0, entry--) { + * while (TLB_Probe_Hit(va)) { + * va += Page_Size; + * } + * TLB_Write(entry, va, 0, 0, 0); + * } + */ +LEAF(tlb_init) + /* Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values + * are zero, and the default page size is used. + */ + mtc0 ZERO, CP0_ENTRYLO0 + /* Clear out PFN and valid bits */ + mtc0 ZERO, CP0_ENTRYLO1 + mtc0 ZERO, CP0_PAGEMASK + /* Clear out mask register */ + /* Start with the base address of kseg0 for the VA part of the TLB */ + li T0, 0x80000000 + /* + * Write the VA candidate to EntryHi and probe the TLB to see if if is + * already there. If it is, a write to the TLB may cause a machine + * check, so just increment the VA candidate by one page and try again. + */ +10: + mtc0 T0, CP0_ENTRYHI + /* Write VA candidate */ + tlbp_write_hazard + /* Clear EntryHi hazard (ssnop/ehb in R1/2) */ + tlbp + /* Probe the TLB to check for a match */ + tlbp_read_hazard + /* Clear Index hazard (ssnop/ehb in R1/2) */ + mfc0 T1, CP0_INDEX + addiu T0, (1 << S_EntryHiVPN2) + /* Read back flag to check for match */ + bgez T1, 10b + nop + /* Add 1 to VPN index in va */ + /* + * A write of the VPN candidate will be unique, so write this entry + * into the next index, decrement the index, and continue until the + * index goes negative (thereby writing all TLB entries) + */ + mtc0 A0, CP0_INDEX + /* Use this as next TLB index */ + tlbw_write_hazard + /* Clear Index hazard (ssnop/ehb in R1/2) */ + tlbwi + /* Write the TLB entry */ + /* Branch if more TLB entries to do */ + addiu A0, A0, -1 + bne A0, ZERO, 10b + nop + + /* Decrement the TLB index */ + /* + * Clear Index and EntryHi simply to leave the state constant for all + * returns + */ + mtc0 ZERO, CP0_INDEX + mtc0 ZERO, CP0_ENTRYHI + jr RA + /* Return to caller */ + nop +END(tlb_init) + +.extern vmm_cpu_handle_pagefault + +LEAF(_handle_tlbmiss) + disable_global_interrupts + move K0, SP + SAVE_INT_CONTEXT(_int_stack) + move A0, SP + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +END(_handle_tlbmiss) + +.extern generic_int_handler +.extern _int_stack +.extern vmm_regs_dump +LEAF(_handle_interrupt) + disable_global_interrupts + SAVE_INT_CONTEXT(_int_stack) + move A0, SP + bal generic_int_handler + nop + RESTORE_INT_CONTEXT(SP) + enable_global_interrupts + eret +END(_handle_interrupt) + +LEAF(_handle_cache_error) + b _handle_cache_error + nop +END(_handle_cache_error) + +LEAF(_handle_general_exception) + //move K0, SP + //SAVE_INT_CONTEXT(_int_stack) + //bal vmm_regs_dump + //move A0, SP + + b _handle_general_exception + nop +END(_handle_general_exception) + +/** + * A0 -> Contains virtual address. + * A1 -> Contains physical address. + * A2 -> TLB index: If -1 select automatically. + */ +.globl create_tlb_entry +LEAF(create_tlb_entry) + mtc0 A2, CP0_INDEX /* load the tlb index to be programmed. */ + srl A0, A0, 12 /* get the VPN */ + sll A0, A0, 12 + nop + mtc0 A0, CP0_ENTRYHI /* load VPN in entry hi */ + addi T0, A1, 0x1000 /* next PFN for entry lo1 in T0 */ + srl A1, A1, 12 /* get the PFN */ + sll A1, A1, 6 /* get the PFN */ + srl T0, T0, 12 + sll T0, T0, 6 + ori A1, A1, 0x7 /* mark the page writable, global and valid */ + mtc0 A1, CP0_ENTRYLO0 + ori T0, T0, 0x7 /* mark the next physical page writable, global and valid */ + nop + nop + mtc0 T0, CP0_ENTRYLO1 + nop + nop + nop + tlbwi + ehb + j RA + nop +END(create_tlb_entry) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h new file mode 100644 index 0000000..6c5cb84 --- /dev/null +++ b/ports/mips/atomport-private.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_PRIVATE_H_ +#define __ATOMPORT_PRIVATE_H_ + +#define zero $0 +#define at $1 +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define t8 $24 +#define t9 $25 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define s8 $30 +#define fp $30 +#define ra $31 + +#define NUM_REGISTERS 32 +#define WORD_SIZE 4 + +#define v0_IDX 0 +#define v1_IDX 1 +#define a0_IDX 2 +#define a1_IDX 3 +#define a2_IDX 4 +#define a3_IDX 5 +#define t0_IDX 6 +#define t1_IDX 7 +#define t2_IDX 8 +#define t3_IDX 9 +#define t4_IDX 10 +#define t5_IDX 11 +#define t6_IDX 12 +#define t7_IDX 13 +#define s0_IDX 14 +#define s1_IDX 15 +#define s2_IDX 16 +#define s3_IDX 17 +#define s4_IDX 18 +#define s5_IDX 19 +#define s6_IDX 20 +#define s7_IDX 21 +#define t8_IDX 22 +#define t9_IDX 23 +#define sp_IDX 24 +#define gp_IDX 25 +#define s8_IDX 26 +#define ra_IDX 27 +#define k0_IDX 28 +#define k1_IDX 29 +#define at_IDX 30 +#define zero_IDX 31 + +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_HWRENA $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_INTCTL $12,1 +#define CP0_SRSCTL $12,2 +#define CP0_SRSMAP $12,3 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_EBASE $15,1 +#define CP0_CONFIG $16 +#define CP0_CONFIG1 $16,1 +#define CP0_CONFIG2 $16,2 +#define CP0_CONFIG3 $16,3 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFCTL $25,0 +#define CP0_PERFCNT $25,1 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_DATALO $28,1 +#define CP0_TAGHI $29 +#define CP0_DATAHI $29,1 +#define CP0_ERRORPC $30 + +#define SAVE_REG(addr, reg, val) \ + sw reg, (reg ## _IDX * WORD_SIZE)(addr) + +#define LOAD_REG(addr, reg, val) \ + lw reg, (reg ## _IDX * WORD_SIZE)(addr) + +#endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h new file mode 100644 index 0000000..5b5a6de --- /dev/null +++ b/ports/mips/atomport-tests.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H +#define __ATOM_PORT_TESTS_H + +/* Include Atomthreads kernel API */ +#include "atom.h" + +/* Logger macro for viewing test results */ +/* FIXME: Add uart out routine once uart is supported */ +#define ATOMLOG(x) +#define _STR(x) + +/* Default thread stack size (in bytes) */ +#define TEST_THREAD_STACK_SIZE 128 + +/* Uncomment to enable logging of stack usage to UART */ +/* #define TESTS_LOG_STACK_USAGE */ + +#endif /* __ATOM_PORT_TESTS_H */ + diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h new file mode 100644 index 0000000..97ba780 --- /dev/null +++ b/ports/mips/atomport-types.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_TYPES_H +#define __ATOMPORT_TYPES_H + +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +#define UINT32 uint32_t + +#endif /* __ATOMPORT_TYPES_H */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c new file mode 100644 index 0000000..4b77a20 --- /dev/null +++ b/ports/mips/atomport.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +/** + * This function initialises each thread's stack during creation, before the + * thread is first run. New threads are scheduled in using the same + * context-switch function used for threads which were previously scheduled + * out, therefore this function should set up a stack context which looks + * much like a thread which has been scheduled out and had its context saved. + * We fill part of the stack with those registers which are involved in the + * context switch, including appropriate stack or register contents to cause + * the thread to branch to its entry point function when it is scheduled in. + * + * Interrupts should also be enabled whenever a thread is restored, hence + * ports may wish to explicitly include the interrupt-enable register here + * which will be restored when the thread is scheduled in. Other methods + * can be used to enable interrupts, however, without explicitly storing + * it in the thread's context. + */ +void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, + void (*entry_point)(UINT32), + UINT32 entry_param) +{ + +#define STORE_VAL(base, reg, val) \ + *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val + + void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS)); + + tcb_ptr->sp_save_ptr = stack_start; + + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); +} + diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h new file mode 100644 index 0000000..9a20931 --- /dev/null +++ b/ports/mips/atomport.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H +#define __ATOM_PORT_H + +#include "atomport-types.h" + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +/** + * Architecture-specific types. + * Most of these are available from stdint.h on this platform, which is + * included above. + */ +#define POINTER void * + +/* Critical region protection */ +#define CRITICAL_STORE +#define CRITICAL_START() __asm__ __volatile__("di $0\n\t") +#define CRITICAL_END() __asm__ __volatile__("ei $0\n\t"); + +/* Uncomment to enable stack-checking */ +/* #define ATOM_STACK_CHECKING */ + +#endif /* __ATOM_PORT_H */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c new file mode 100644 index 0000000..0ab9a94 --- /dev/null +++ b/ports/mips/tests-main.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010, Kelvin Lawson. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atom.h" +#include "atomport-private.h" +#include "atomtests.h" +#include "atomtimer.h" + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + * + * In this case, the idle stack is allocated on the BSS via the + * idle_thread_stack[] byte array. + */ +#define IDLE_STACK_SIZE_BYTES 128 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop + * flashing a LED. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + * + * With all OS tests implemented to date on the AVR, the Main thread + * stack has not exceeded 198 bytes. To allow all tests to run we set + * a minimum main thread stack size of 204 bytes. This may increase in + * future as the codebase changes but for the time being is enough to + * cope with all of the automated tests. + */ +#define MAIN_STACK_SIZE_BYTES 204 + + +/* + * Startup code stack + * + * Some stack space is required at initial startup for running the main() + * routine. This stack space is only temporarily required at first bootup + * and is no longer required as soon as the OS is started. By default + * GCC sets this to the top of RAM (RAMEND) and it grows down from there. + * Because we only need this temporarily, though, it would be wasteful to + * set aside a region at the top of RAM which is not used during runtime. + * + * What we do here is to reuse part of the idle thread's stack during + * initial startup. As soon as we enter the main() routine we move the + * stack pointer to half-way down the idle thread's stack. This is used + * temporarily while calls are made to atomOSInit(), atomThreadCreate() + * and atomOSStart(). Once the OS is started this stack area is no + * longer required, and can be used for its original purpose (for the + * idle thread's stack). + * + * This does mean, however, that we cannot monitor the stack usage of the + * idle thread. Stack usage is monitored by prefilling the stack with a + * known value, and we are obliterating some of that prefilled area by + * using it as our startup stack, so we cannot use the stack-checking API + * to get a true picture of idle thread stack usage. If you wish to + * monitor idle thread stack usage for your applications then you are + * free to use a different region for the startup stack (e.g. set aside + * an area permanently, or place it somewhere you know you can reuse + * later in the application). For the time being, this method gives us a + * simple way of reducing the memory consumption without having to add + * any special AVR-specific considerations to the automated test + * applications. + * + * This optimisation was required to allow some of the larger automated + * test modules to run on devices with 1KB of RAM. You should avoid doing + * this if you can afford to set aside 64 bytes or so, or if you are + * writing your own applications in which you have further control over + * where data is located. + */ + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + +/* STDIO stream */ +static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); + + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + + +/** + * \b main + * + * Program entry point. + * + * Sets up the AVR hardware resources (system tick timer interrupt) necessary + * for the OS to be started. Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + /** + * Reuse part of the idle thread's stack for the stack required + * during this startup function. + */ + SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1]; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /** + * Initialise the OS before creating our threads. + * + * Note that we tell the OS that the idle stack is half its actual + * size. This prevents it prefilling the bottom half with known + * values for stack-checkig purposes, which we cannot allow because + * we are temporarily using it for our own stack. The remainder will + * still be available once the OS is started, this only prevents the + * OS from prefilling it. + * + * If you are not reusing the idle thread's stack during startup then + * you should pass in the correct size here. + */ + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + if (status == ATOM_OK) + { + /* Enable the system tick timer */ + avrInitSystemTickTimer(); + + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], + MAIN_STACK_SIZE_BYTES); + if (status == ATOM_OK) + { + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1) + ; + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + uint32_t test_status; + int sleep_ticks; + + /* Enable all LEDs (STK500-specific) */ + DDRB = 0xFF; + PORTB = 0xFF; + + /* Initialise UART (9600bps) */ + if (uart_init(9600) != 0) + { + /* Error initialising UART */ + } + + /** + * Redirect stdout via the UART. Note that the UART write routine + * is protected via a semaphore, so the OS must be started before + * use of the UART. + */ + stdout = &uart_stdout; + + /* Put a message out on the UART */ + printf_P(PSTR("Go\n")); + + /* Start test. All tests use the same start API. */ + test_status = test_start(); + + /* Check main thread stack usage (if enabled) */ +#ifdef ATOM_STACK_CHECKING + if (test_status == 0) + { + uint32_t used_bytes, free_bytes; + + /* Check idle thread stack usage */ + if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) + { + /* Check the thread did not use up to the end of stack */ + if (free_bytes == 0) + { + printf_P (PSTR("Main stack overflow\n")); + test_status++; + } + + /* Log the stack usage */ +#ifdef TESTS_LOG_STACK_USAGE + printf_P (PSTR("MainUse:%d\n"), used_bytes); +#endif + } + + } +#endif + + /* Log final status */ + if (test_status == 0) + { + printf_P (PSTR("Pass\n")); + } + else + { + printf_P (PSTR("Fail(%d)\n"), test_status); + } + + /* Flash LED once per second if passed, very quickly if failed */ + sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8); + + /* Test finished, flash slowly for pass, fast for fail */ + while (1) + { + /* Toggle a LED (STK500-specific) */ + PORTB ^= (1 << 7); + + /* Sleep then toggle LED again */ + atomTimerDelay(sleep_ticks); + } + +} From ac40279132f7b2daa2f0f346a7a2bfcc786496e8 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 02/76] Compilable MIPS code. Signed-off-by: Himanshu Chauhan --- kernel/atom-types.h | 37 ++++ kernel/atomkernel.c | 6 +- kernel/atommutex.c | 6 +- kernel/atomqueue.c | 6 +- kernel/atomsem.c | 8 +- kernel/atomtimer.c | 6 +- ports/mips/8250-serial.c | 80 +++++++ ports/mips/8250-serial.h | 346 +++++++++++++++++++++++++++++++ ports/mips/Makefile | 64 ++++-- ports/mips/atomport-asm-macros.h | 285 +++++++++++++++++++++++++ ports/mips/atomport-entry.s | 231 ++++++--------------- ports/mips/atomport-private.h | 6 - ports/mips/atomport-tests.h | 4 +- ports/mips/atomport-types.h | 2 + ports/mips/io.c | 44 ++++ ports/mips/linker.ld | 74 +++++++ ports/mips/printk.c | 61 ++++++ ports/mips/printk.h | 43 ++++ ports/mips/stdarg.h | 28 +++ ports/mips/string.c | 61 ++++++ ports/mips/string.h | 42 ++++ ports/mips/system.h | 52 +++++ ports/mips/tests-main.c | 90 +------- ports/mips/vsprintf.c | 244 ++++++++++++++++++++++ tests/kern1.c | 7 +- tests/kern2.c | 3 + tests/kern3.c | 3 + tests/kern4.c | 3 + tests/mutex1.c | 7 +- tests/mutex2.c | 7 +- tests/mutex3.c | 5 +- tests/mutex4.c | 8 +- tests/mutex5.c | 8 +- tests/mutex6.c | 9 +- tests/mutex7.c | 7 +- tests/mutex8.c | 6 + tests/mutex9.c | 6 + tests/queue1.c | 7 +- tests/queue10.c | 6 + tests/queue2.c | 6 + tests/queue3.c | 6 + tests/queue4.c | 7 +- tests/queue5.c | 6 + tests/queue6.c | 6 + tests/queue7.c | 6 + tests/queue8.c | 6 + tests/queue9.c | 6 + tests/sem1.c | 7 +- tests/sem2.c | 9 +- tests/sem3.c | 6 + tests/sem4.c | 6 + tests/sem5.c | 6 + tests/sem6.c | 6 + tests/sem7.c | 6 + tests/sem8.c | 6 + tests/sem9.c | 6 + tests/timer1.c | 9 +- tests/timer2.c | 6 + tests/timer3.c | 9 +- tests/timer4.c | 8 +- tests/timer5.c | 9 +- tests/timer6.c | 8 +- tests/timer7.c | 6 + 63 files changed, 1784 insertions(+), 296 deletions(-) create mode 100755 kernel/atom-types.h create mode 100644 ports/mips/8250-serial.c create mode 100644 ports/mips/8250-serial.h create mode 100644 ports/mips/atomport-asm-macros.h create mode 100644 ports/mips/io.c create mode 100755 ports/mips/linker.ld create mode 100644 ports/mips/printk.c create mode 100644 ports/mips/printk.h create mode 100755 ports/mips/stdarg.h create mode 100644 ports/mips/string.c create mode 100644 ports/mips/string.h create mode 100644 ports/mips/system.h create mode 100644 ports/mips/vsprintf.c diff --git a/kernel/atom-types.h b/kernel/atom-types.h new file mode 100755 index 0000000..898e2ca --- /dev/null +++ b/kernel/atom-types.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_TYPES_H +#define __ATOM_TYPES_H + +#include + +#define NULL ((void *)(0)) + +#endif /* __ATOM_TYPES_H */ diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 97daac4..6952576 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -143,8 +143,12 @@ * */ - +#ifndef STAND_ALONE #include +#else +#include +#endif + #include "atom.h" diff --git a/kernel/atommutex.c b/kernel/atommutex.c index cbb6371..fdb4fff 100755 --- a/kernel/atommutex.c +++ b/kernel/atommutex.c @@ -100,8 +100,12 @@ * */ - +#ifndef STAND_ALONE #include +#else +#include +#endif + #include "atom.h" #include "atommutex.h" #include "atomtimer.h" diff --git a/kernel/atomqueue.c b/kernel/atomqueue.c index 78599f5..70a65aa 100755 --- a/kernel/atomqueue.c +++ b/kernel/atomqueue.c @@ -90,8 +90,12 @@ * */ - +#ifndef STAND_ALONE #include +#else +#include +#endif + #include #include "atom.h" diff --git a/kernel/atomsem.c b/kernel/atomsem.c index 6c5d32d..d78bccc 100755 --- a/kernel/atomsem.c +++ b/kernel/atomsem.c @@ -87,8 +87,14 @@ * */ - +#ifndef STAND_ALONE #include +#endif + +#ifdef STAND_ALONE +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtimer.h" diff --git a/kernel/atomtimer.c b/kernel/atomtimer.c index 5376fcb..136bf59 100755 --- a/kernel/atomtimer.c +++ b/kernel/atomtimer.c @@ -66,8 +66,12 @@ * */ - +#ifndef STAND_ALONE #include +#else +#include +#endif + #include "atom.h" diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c new file mode 100644 index 0000000..a7a3f59 --- /dev/null +++ b/ports/mips/8250-serial.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include +#include +#include <8250-serial.h> + +#define PORT1 (void *)0x140003f8 +#define PORT2 (void *)0x140002F8 +#define PORT3 (void *)0x140003E8 +#define PORT4 (void *)0x140002E8 + +static inline unsigned int serial_in(int offset) +{ + return ioreadb(PORT1 + offset); +} + +static inline void serial_out(int offset, int value) +{ + iowriteb(PORT1 + offset, value); +} + +int putch(uint8_t c) +{ + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(UART_TX, c); + + return 1; +} + +void init_console() +{ + serial_out(1 , 0); /* Turn off interrupts */ + + /* Communication Settings */ + serial_out(3 , 0x80); /* SET DLAB ON */ + serial_out(0 , 0x01); /* Set Baud rate - Divisor Latch Low Byte */ + /* 0x03 = 38,400 BPS */ + /* Default 0x01 = 115,200 BPS */ + /* 0x02 = 57,600 BPS */ + /* 0x06 = 19,200 BPS */ + /* 0x0C = 9,600 BPS */ + /* 0x18 = 4,800 BPS */ + /* 0x30 = 2,400 BPS */ + serial_out(1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */ + serial_out(3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ + serial_out(2 , 0xC7); /* FIFO Control Register */ + serial_out(4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ +} diff --git a/ports/mips/8250-serial.h b/ports/mips/8250-serial.h new file mode 100644 index 0000000..c7907a1 --- /dev/null +++ b/ports/mips/8250-serial.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _8250_SERIAL_H +#define _8250_SERIAL_H + +/* + * DLAB=0 + */ +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ +/* + * Sleep mode for ST16650 and TI16750. For the ST16650, EFR[4]=1 + */ +#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */ +#define UART_IIR_MSI 0x00 /* Modem status interrupt */ +#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */ +#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ +#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ + +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ +/* + * Note: The FIFO trigger levels are chip specific: + * RX:76 = 00 01 10 11 TX:54 = 00 01 10 11 + * PC16550D: 1 4 8 14 xx xx xx xx + * TI16C550A: 1 4 8 14 xx xx xx xx + * TI16C550C: 1 4 8 14 xx xx xx xx + * ST16C550: 1 4 8 14 xx xx xx xx + * ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2 + * NS16C552: 1 4 8 14 xx xx xx xx + * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 + * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 + * TI16C752: 8 16 56 60 8 16 32 56 + */ +#define UART_FCR_R_TRIG_00 0x00 +#define UART_FCR_R_TRIG_01 0x40 +#define UART_FCR_R_TRIG_10 0x80 +#define UART_FCR_R_TRIG_11 0xc0 +#define UART_FCR_T_TRIG_00 0x00 +#define UART_FCR_T_TRIG_01 0x10 +#define UART_FCR_T_TRIG_10 0x20 +#define UART_FCR_T_TRIG_11 0x30 + +#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ +#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ +#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ +#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ +#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ +/* 16650 definitions */ +#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */ +#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */ +#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */ +#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */ +#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */ +#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ +#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ +#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ +#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750) */ + +#define UART_LCR 3 /* Out: Line Control Register */ +/* + * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting + * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. + */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_SBC 0x40 /* Set break control */ +#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ +#define UART_LCR_EPAR 0x10 /* Even parity select */ +#define UART_LCR_PARITY 0x08 /* Parity Enable */ +#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */ +#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ +#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ +#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ +#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */ +#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */ +#define UART_MCR_XONANY 0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */ +#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */ +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ +#define UART_MCR_OUT2 0x08 /* Out2 complement */ +#define UART_MCR_OUT1 0x04 /* Out1 complement */ +#define UART_MCR_RTS 0x02 /* RTS complement */ +#define UART_MCR_DTR 0x01 /* DTR complement */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_TEMT 0x40 /* Transmitter empty */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_FE 0x08 /* Frame error indicator */ +#define UART_LSR_PE 0x04 /* Parity error indicator */ +#define UART_LSR_OE 0x02 /* Overrun error indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ + +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ +#define UART_MSR_RI 0x40 /* Ring Indicator */ +#define UART_MSR_DSR 0x20 /* Data Set Ready */ +#define UART_MSR_CTS 0x10 /* Clear to Send */ +#define UART_MSR_DDCD 0x08 /* Delta DCD */ +#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ +#define UART_MSR_DDSR 0x02 /* Delta DSR */ +#define UART_MSR_DCTS 0x01 /* Delta CTS */ +#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ + +#define UART_SCR 7 /* I/O: Scratch Register */ + +/* + * DLAB=1 + */ +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ + +/* + * LCR=0xBF (or DLAB=1 for 16C660) + */ +#define UART_EFR 2 /* I/O: Extended Features Register */ +#define UART_EFR_CTS 0x80 /* CTS flow control */ +#define UART_EFR_RTS 0x40 /* RTS flow control */ +#define UART_EFR_SCD 0x20 /* Special character detect */ +#define UART_EFR_ECB 0x10 /* Enhanced control bit */ +/* + * the low four bits control software flow control + */ + +/* + * LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654 + */ +#define UART_XON1 4 /* I/O: Xon character 1 */ +#define UART_XON2 5 /* I/O: Xon character 2 */ +#define UART_XOFF1 6 /* I/O: Xoff character 1 */ +#define UART_XOFF2 7 /* I/O: Xoff character 2 */ + +/* + * EFR[4]=1 MCR[6]=1, TI16C752 + */ +#define UART_TI752_TCR 6 /* I/O: transmission control register */ +#define UART_TI752_TLR 7 /* I/O: trigger level register */ + +/* + * LCR=0xBF, XR16C85x + */ +#define UART_TRG 0 /* FCTR bit 7 selects Rx or Tx + * In: Fifo count + * Out: Fifo custom trigger levels */ +/* + * These are the definitions for the Programmable Trigger Register + */ +#define UART_TRG_1 0x01 +#define UART_TRG_4 0x04 +#define UART_TRG_8 0x08 +#define UART_TRG_16 0x10 +#define UART_TRG_32 0x20 +#define UART_TRG_64 0x40 +#define UART_TRG_96 0x60 +#define UART_TRG_120 0x78 +#define UART_TRG_128 0x80 + +#define UART_FCTR 1 /* Feature Control Register */ +#define UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */ +#define UART_FCTR_RTS_4DELAY 0x01 +#define UART_FCTR_RTS_6DELAY 0x02 +#define UART_FCTR_RTS_8DELAY 0x03 +#define UART_FCTR_IRDA 0x04 /* IrDa data encode select */ +#define UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */ +#define UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */ +#define UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */ +#define UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */ +#define UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */ +#define UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */ +#define UART_FCTR_RX 0x00 /* Programmable trigger mode select */ +#define UART_FCTR_TX 0x80 /* Programmable trigger mode select */ + +/* + * LCR=0xBF, FCTR[6]=1 + */ +#define UART_EMSR 7 /* Extended Mode Select Register */ +#define UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */ +#define UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */ + +/* + * The Intel XScale on-chip UARTs define these bits + */ +#define UART_IER_DMAE 0x80 /* DMA Requests Enable */ +#define UART_IER_UUE 0x40 /* UART Unit Enable */ +#define UART_IER_NRZE 0x20 /* NRZ coding Enable */ +#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */ + +#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ + +#define UART_FCR_PXAR1 0x00 /* receive FIFO threshold = 1 */ +#define UART_FCR_PXAR8 0x40 /* receive FIFO threshold = 8 */ +#define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ +#define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ + + + + +/* + * These register definitions are for the 16C950 + */ +#define UART_ASR 0x01 /* Additional Status Register */ +#define UART_RFL 0x03 /* Receiver FIFO level */ +#define UART_TFL 0x04 /* Transmitter FIFO level */ +#define UART_ICR 0x05 /* Index Control Register */ + +/* The 16950 ICR registers */ +#define UART_ACR 0x00 /* Additional Control Register */ +#define UART_CPR 0x01 /* Clock Prescalar Register */ +#define UART_TCR 0x02 /* Times Clock Register */ +#define UART_CKS 0x03 /* Clock Select Register */ +#define UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */ +#define UART_RTL 0x05 /* Receiver Interrupt Trigger Level */ +#define UART_FCL 0x06 /* Flow Control Level Lower */ +#define UART_FCH 0x07 /* Flow Control Level Higher */ +#define UART_ID1 0x08 /* ID #1 */ +#define UART_ID2 0x09 /* ID #2 */ +#define UART_ID3 0x0A /* ID #3 */ +#define UART_REV 0x0B /* Revision */ +#define UART_CSR 0x0C /* Channel Software Reset */ +#define UART_NMR 0x0D /* Nine-bit Mode Register */ +#define UART_CTR 0xFF + +/* + * The 16C950 Additional Control Register + */ +#define UART_ACR_RXDIS 0x01 /* Receiver disable */ +#define UART_ACR_TXDIS 0x02 /* Transmitter disable */ +#define UART_ACR_DSRFC 0x04 /* DSR Flow Control */ +#define UART_ACR_TLENB 0x20 /* 950 trigger levels enable */ +#define UART_ACR_ICRRD 0x40 /* ICR Read enable */ +#define UART_ACR_ASREN 0x80 /* Additional status enable */ + + + +/* + * These definitions are for the RSA-DV II/S card, from + * + * Kiyokazu SUTO + */ + +#define UART_RSA_BASE (-8) + +#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */ + +#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */ +#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */ +#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */ +#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */ + +#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */ + +#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */ +#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */ +#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */ + +#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */ + +#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */ +#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */ +#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */ +#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occurred (1) */ +#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occurred */ + +#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */ + +#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */ + +#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */ + +#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */ + +/* + * The RSA DSV/II board has two fixed clock frequencies. One is the + * standard rate, and the other is 8 times faster. + */ +#define SERIAL_RSA_BAUD_BASE (921600) +#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) + +/* + * Extra serial register definitions for the internal UARTs + * in TI OMAP processors. + */ +#define UART_OMAP_MDR1 0x08 /* Mode definition register */ +#define UART_OMAP_MDR2 0x09 /* Mode definition register 2 */ +#define UART_OMAP_SCR 0x10 /* Supplementary control register */ +#define UART_OMAP_SSR 0x11 /* Supplementary status register */ +#define UART_OMAP_EBLR 0x12 /* BOF length register */ +#define UART_OMAP_OSC_12M_SEL 0x13 /* OMAP1510 12MHz osc select */ +#define UART_OMAP_MVER 0x14 /* Module version register */ +#define UART_OMAP_SYSC 0x15 /* System configuration register */ +#define UART_OMAP_SYSS 0x16 /* System status register */ +#define UART_OMAP_WER 0x17 /* Wake-up enable register */ + +#endif /* _8250_SERIAL_H */ + diff --git a/ports/mips/Makefile b/ports/mips/Makefile index 016c290..dc90cdf 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -14,6 +14,24 @@ TESTS_DIR=../../tests CC=mips-linux-gnu-gcc OBJCOPY=mips-linux-gnu-objcopy +# Check if verbosity is ON for build process +VERBOSE_DEFAULT := 0 +CMD_PREFIX_DEFAULT := @ +ifdef VERBOSE + ifeq ("$(origin VERBOSE)", "command line") + VB := $(VERBOSE) + else + VB := $(VERBOSE_DEFAULT) + endif +else + VB := $(VERBOSE_DEFAULT) +endif +ifeq ($(VB), 1) + V := +else + V := $(CMD_PREFIX_DEFAULT) +endif + # Enable stack-checking. WARNING: the full automated test suite currently # requires a little over 1KB RAM with stack-checking enabled. If you are # using a device with 1KB internal SRAM and no external SRAM then you @@ -24,14 +42,15 @@ OBJCOPY=mips-linux-gnu-objcopy BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o test-main.o -APP_ASM_OBJECTS = atomport-asm.o atomport-entry.o +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o + +APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o # Kernel object files KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o # Collection of built objects (excluding test applications) -ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) +ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) # Test object files (dealt with separately as only one per application build) @@ -47,14 +66,23 @@ vpath %.elf ./$(BUILD_DIR) vpath %.hex ./$(BUILD_DIR) # GCC flags -CFLAGS=-g -Wall -Werror +CFLAGS= -g \ + -Wall \ + -Werror \ + -O \ + -fstrength-reduce \ + -fomit-frame-pointer \ + -finline-functions \ + -nostdinc \ + -fno-builtin \ + -fno-stack-protector \ + -DSTAND_ALONE # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) CFLAGS += -DATOM_STACK_CHECKING endif - ################# # Build targets # ################# @@ -68,36 +96,42 @@ $(BUILD_DIR): # Test HEX files (one application build for each test) $(TEST_HEXS): %.hex: %.elf - @echo Building $@ - $(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + $(if $(V), @echo " (HEX) $(subst $(build_dir)/,,$@)") + $(V)$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ # Test ELF files (one application build for each test) -$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS) - $(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map +$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl -T linker.ld # Kernel objects builder $(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c - $(CC) -c $(CFLAGS) -I. $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Test objects builder $(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c - $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Application C objects builder $(APP_OBJECTS): %.o: ./%.c - $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Application asm objects builder $(APP_ASM_OBJECTS): %.o: ./%.s - $(CC) -c $(CFLAGS) -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # .lst file builder %.lst: %.c - $(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ # Clean clean: - rm -f *.o *.elf *.map *.hex *.bin *.lst + $(V)rm -f *.o *.elf *.map *.hex *.bin *.lst rm -rf doxygen-kernel rm -rf doxygen-avr rm -rf build diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h new file mode 100644 index 0000000..c71f1e1 --- /dev/null +++ b/ports/mips/atomport-asm-macros.h @@ -0,0 +1,285 @@ +#ifndef __ATOMPORT_ASM_MACROS_H_ +#define __ATOMPORT_ASM_MACROS_H_ + +#include + +#ifdef __ASSEMBLY__ /* to be called only from assembly */ + +#define LEAF(fn) \ + .globl fn; \ + .ent fn; \ +fn: + +#define END(fn) \ + .size fn,.-fn; \ + .end fn + +#define tlbp_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbp_read_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbw_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define enable_global_interrupts ei $0 +#define disable_global_interrupts di $0 + +#define EXCEPTION_VECTOR(_name, _offset, _where)\ + . = _offset; \ + .set noreorder; \ +_name: \ + b _where; \ + nop; + +#define SAVE_REG(reg, treg) \ + sw reg, ((reg ## _IDX) * 4)(treg) + +#define LOAD_REG(reg, treg) \ + lw reg, ((reg ## _IDX) * 4)(treg) + +#define SAVE_INT_CONTEXT(_int_sp) \ + move k0, sp; \ + la sp, _int_sp; \ + addiu sp, sp, -((CPU_USER_REG_COUNT + 1)* 4); \ + mfc0 k1, CP0_EPC; \ + SAVE_REG(v0,sp); \ + SAVE_REG(v1,sp); \ + SAVE_REG(a0,sp); \ + SAVE_REG(a1,sp); \ + SAVE_REG(a2,sp); \ + SAVE_REG(a3,sp); \ + SAVE_REG(t0,sp); \ + SAVE_REG(t1,sp); \ + SAVE_REG(t2,sp); \ + SAVE_REG(t3,sp); \ + SAVE_REG(t4,sp); \ + SAVE_REG(t5,sp); \ + SAVE_REG(t6,sp); \ + SAVE_REG(t7,sp); \ + SAVE_REG(s0,sp); \ + SAVE_REG(s1,sp); \ + SAVE_REG(s2,sp); \ + SAVE_REG(s3,sp); \ + SAVE_REG(s4,sp); \ + SAVE_REG(s5,sp); \ + SAVE_REG(s6,sp); \ + SAVE_REG(s7,sp); \ + SAVE_REG(t8,sp); \ + SAVE_REG(t9,sp); \ + SAVE_REG(gp,sp); \ + SAVE_REG(s8,sp); \ + SAVE_REG(ra,sp); \ + sw k0, (sp_IDX * 4)(sp); \ + sw k1, (CPU_USER_REG_COUNT * 4)(sp); + +#define RESTORE_INT_CONTEXT(treg) \ + lw k1, (CPU_USER_REG_COUNT * 4)(treg); \ + mtc0 k1, CP0_EPC; \ + LOAD_REG(v0,treg); \ + LOAD_REG(v1,treg); \ + LOAD_REG(a0,treg); \ + LOAD_REG(a1,treg); \ + LOAD_REG(a2,treg); \ + LOAD_REG(a3,treg); \ + LOAD_REG(t0,treg); \ + LOAD_REG(t1,treg); \ + LOAD_REG(t2,treg); \ + LOAD_REG(t3,treg); \ + LOAD_REG(t4,treg); \ + LOAD_REG(t5,treg); \ + LOAD_REG(t6,treg); \ + LOAD_REG(t7,treg); \ + LOAD_REG(s0,treg); \ + LOAD_REG(s1,treg); \ + LOAD_REG(s2,treg); \ + LOAD_REG(s3,treg); \ + LOAD_REG(s4,treg); \ + LOAD_REG(s5,treg); \ + LOAD_REG(s6,treg); \ + LOAD_REG(s7,treg); \ + LOAD_REG(t8,treg); \ + LOAD_REG(t9,treg); \ + LOAD_REG(gp,treg); \ + LOAD_REG(ra,treg); \ + LOAD_REG(s8,treg); \ + lw sp, (sp_IDX * 4)(treg); + +#endif /* __ASSEMBLY__ */ + +#define num_to_string(s) to_string(s) +#define to_string(s) #s + +#define IASM_SAVE_REG(reg, here) \ + "sw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + +#define IASM_LOAD_REG(reg, here) \ + "lw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + + +/* + * Macros to be used with C code. + */ +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + (unsigned long) __read_32bit_c0_register(reg, sel) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + __write_32bit_c0_register(reg, sel, val); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20) +#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* MIPSR2 */ +#define read_c0_hwrena() __read_32bit_c0_register($7, 0) +#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_intctl() __read_32bit_c0_register($12, 1) +#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val) + +#define read_c0_srsctl() __read_32bit_c0_register($12, 2) +#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val) + +#define read_c0_srsmap() __read_32bit_c0_register($12, 3) +#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val) + +#define read_c0_ebase() __read_32bit_c0_register($15, 1) +#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) + +#endif /* __ATOMPORT_ASM_MACROS_H_ */ diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index c746923..508ea5d 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -1,28 +1,33 @@ -/** - * Copyright (c) 2010 Himanshu Chauhan. - * All rights reserved. +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * @file start.S - * @version 0.1 - * @author Himanshu Chauhan (hschauhan@nulltrace.org) - * @brief 24Kc startup file. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atomport-private.h" +#include "atomport-asm-macros.h" .extern _stack_start .section .start.text,"ax",@progbits @@ -34,7 +39,7 @@ EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception) EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt) LEAF(_start) - mtc0 ZERO, CP0_CONTEXT + mtc0 zero, CP0_CONTEXT nop nop nop @@ -43,143 +48,42 @@ LEAF(_start) disable_global_interrupts /* clear CPU timer counters. We don't want surprises. */ - mtc0 ZERO, CP0_COMPARE - mtc0 ZERO, CP0_COUNT + mtc0 zero, CP0_COMPARE + mtc0 zero, CP0_COUNT - /* Read number of tlb entries from config register */ - bal num_tlb_entries - nop - - /* initialize tlb */ - bal tlb_init - move A0, V0 - - la SP, _stack_start /* setup the stack (bss segment) */ - la T0, cpu_init - j T0 /* Call the C- code now */ + la sp, _stack_start /* setup the stack (bss segment) */ + la t0, main + j t0 /* Call the C- code now */ nop 1: b 1b /* we should not come here whatsoever */ END(_start) -/* - * Read config 1 register and return the number - * of TLB entries in this CPU. - */ -LEAF(num_tlb_entries) - mfc0 A1, CP0_CONFIG1 - nop - nop - nop - srl V0, A1, 25 - and V0, V0, 0x3F - jr RA - nop -END(num_tlb_entries) - -/** - * tlb_init - * Initialize the TLB to a power-up state, guaranteeing that all entries - * are unique and invalid. - * Arguments: - * a0 = Maximum TLB index (from MMUSize field of C0_Config1) - * Returns: - * No value - * Restrictions: - * This routine must be called in unmapped space - * Algorithm: - * va = kseg0_base; - * for (entry = max_TLB_index ; entry >= 0, entry--) { - * while (TLB_Probe_Hit(va)) { - * va += Page_Size; - * } - * TLB_Write(entry, va, 0, 0, 0); - * } - */ -LEAF(tlb_init) - /* Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values - * are zero, and the default page size is used. - */ - mtc0 ZERO, CP0_ENTRYLO0 - /* Clear out PFN and valid bits */ - mtc0 ZERO, CP0_ENTRYLO1 - mtc0 ZERO, CP0_PAGEMASK - /* Clear out mask register */ - /* Start with the base address of kseg0 for the VA part of the TLB */ - li T0, 0x80000000 - /* - * Write the VA candidate to EntryHi and probe the TLB to see if if is - * already there. If it is, a write to the TLB may cause a machine - * check, so just increment the VA candidate by one page and try again. - */ -10: - mtc0 T0, CP0_ENTRYHI - /* Write VA candidate */ - tlbp_write_hazard - /* Clear EntryHi hazard (ssnop/ehb in R1/2) */ - tlbp - /* Probe the TLB to check for a match */ - tlbp_read_hazard - /* Clear Index hazard (ssnop/ehb in R1/2) */ - mfc0 T1, CP0_INDEX - addiu T0, (1 << S_EntryHiVPN2) - /* Read back flag to check for match */ - bgez T1, 10b - nop - /* Add 1 to VPN index in va */ - /* - * A write of the VPN candidate will be unique, so write this entry - * into the next index, decrement the index, and continue until the - * index goes negative (thereby writing all TLB entries) - */ - mtc0 A0, CP0_INDEX - /* Use this as next TLB index */ - tlbw_write_hazard - /* Clear Index hazard (ssnop/ehb in R1/2) */ - tlbwi - /* Write the TLB entry */ - /* Branch if more TLB entries to do */ - addiu A0, A0, -1 - bne A0, ZERO, 10b - nop - - /* Decrement the TLB index */ - /* - * Clear Index and EntryHi simply to leave the state constant for all - * returns - */ - mtc0 ZERO, CP0_INDEX - mtc0 ZERO, CP0_ENTRYHI - jr RA - /* Return to caller */ - nop -END(tlb_init) - .extern vmm_cpu_handle_pagefault LEAF(_handle_tlbmiss) - disable_global_interrupts - move K0, SP - SAVE_INT_CONTEXT(_int_stack) - move A0, SP - bal vmm_cpu_handle_pagefault - nop - enable_global_interrupts - eret + //disable_global_interrupts + //move k0, sp + //SAVE_INT_CONTEXT(_int_stack) + //move a0, sp + //bal vmm_cpu_handle_pagefault + //nop + //enable_global_interrupts + //eret END(_handle_tlbmiss) .extern generic_int_handler .extern _int_stack .extern vmm_regs_dump LEAF(_handle_interrupt) - disable_global_interrupts - SAVE_INT_CONTEXT(_int_stack) - move A0, SP - bal generic_int_handler - nop - RESTORE_INT_CONTEXT(SP) - enable_global_interrupts - eret + //disable_global_interrupts + //SAVE_INT_CONTEXT(_int_stack) + //move a0, sp + //bal generic_int_handler + //nop + //RESTORE_INT_CONTEXT(sp) + //enable_global_interrupts + //eret END(_handle_interrupt) LEAF(_handle_cache_error) @@ -188,43 +92,38 @@ LEAF(_handle_cache_error) END(_handle_cache_error) LEAF(_handle_general_exception) - //move K0, SP - //SAVE_INT_CONTEXT(_int_stack) - //bal vmm_regs_dump - //move A0, SP - b _handle_general_exception nop END(_handle_general_exception) /** - * A0 -> Contains virtual address. - * A1 -> Contains physical address. - * A2 -> TLB index: If -1 select automatically. + * a0 -> Contains virtual address. + * a1 -> Contains physical address. + * a2 -> TLB index: If -1 select automatically. */ .globl create_tlb_entry LEAF(create_tlb_entry) - mtc0 A2, CP0_INDEX /* load the tlb index to be programmed. */ - srl A0, A0, 12 /* get the VPN */ - sll A0, A0, 12 + mtc0 a2, CP0_INDEX /* load the tlb index to be programmed. */ + srl a0, a0, 12 /* get the VPN */ + sll a0, a0, 12 nop - mtc0 A0, CP0_ENTRYHI /* load VPN in entry hi */ - addi T0, A1, 0x1000 /* next PFN for entry lo1 in T0 */ - srl A1, A1, 12 /* get the PFN */ - sll A1, A1, 6 /* get the PFN */ - srl T0, T0, 12 - sll T0, T0, 6 - ori A1, A1, 0x7 /* mark the page writable, global and valid */ - mtc0 A1, CP0_ENTRYLO0 - ori T0, T0, 0x7 /* mark the next physical page writable, global and valid */ + mtc0 a0, CP0_ENTRYHI /* load VPN in entry hi */ + addi t0, a1, 0x1000 /* next PFN for entry lo1 in T0 */ + srl a1, a1, 12 /* get the PFN */ + sll a1, a1, 6 /* get the PFN */ + srl t0, t0, 12 + sll t0, t0, 6 + ori a1, a1, 0x7 /* mark the page writable, global and valid */ + mtc0 a1, CP0_ENTRYLO0 + ori t0, t0, 0x7 /* mark the next physical page writable, global and valid */ nop nop - mtc0 T0, CP0_ENTRYLO1 + mtc0 t0, CP0_ENTRYLO1 nop nop nop tlbwi ehb - j RA + j ra nop END(create_tlb_entry) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h index 6c5cb84..e2af7e0 100644 --- a/ports/mips/atomport-private.h +++ b/ports/mips/atomport-private.h @@ -139,10 +139,4 @@ #define CP0_DATAHI $29,1 #define CP0_ERRORPC $30 -#define SAVE_REG(addr, reg, val) \ - sw reg, (reg ## _IDX * WORD_SIZE)(addr) - -#define LOAD_REG(addr, reg, val) \ - lw reg, (reg ## _IDX * WORD_SIZE)(addr) - #endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h index 5b5a6de..66b58eb 100644 --- a/ports/mips/atomport-tests.h +++ b/ports/mips/atomport-tests.h @@ -35,8 +35,8 @@ /* Logger macro for viewing test results */ /* FIXME: Add uart out routine once uart is supported */ -#define ATOMLOG(x) -#define _STR(x) +#define ATOMLOG printk +#define _STR /* Default thread stack size (in bytes) */ #define TEST_THREAD_STACK_SIZE 128 diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h index 97ba780..b5c10f9 100644 --- a/ports/mips/atomport-types.h +++ b/ports/mips/atomport-types.h @@ -36,6 +36,8 @@ typedef signed char int8_t; typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; #define UINT32 uint32_t diff --git a/ports/mips/io.c b/ports/mips/io.c new file mode 100644 index 0000000..0ce15c4 --- /dev/null +++ b/ports/mips/io.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 + +uint8_t ioreadb (void *addr) +{ + uint8_t rv; + rv = *((volatile uint8_t *)addr); + return rv; +} + +void iowriteb (void *addr, uint8_t data) +{ + *(volatile uint8_t *)addr = data; +} + diff --git a/ports/mips/linker.ld b/ports/mips/linker.ld new file mode 100755 index 0000000..98d6df6 --- /dev/null +++ b/ports/mips/linker.ld @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-tradbigmips") +OUTPUT_ARCH("mips") +ENTRY(_start) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.start.text) + *(.text) + . = ALIGN(4); + _etext = .; + } + + .data : + { + *(.data) + . = ALIGN(4); + _edata = .; + } + + .bss : + { + *(.bss) + . = ALIGN(4); + _ebss = .; + } + + .rodata : + { + *(.rodata .rodata.*) + . = ALIGN(4); + _erodata = .; + } + + PROVIDE(_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_stack_start = .); + PROVIDE(_int_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_int_stack = .); +} diff --git a/ports/mips/printk.c b/ports/mips/printk.c new file mode 100644 index 0000000..1ef0f64 --- /dev/null +++ b/ports/mips/printk.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +#include + +static int8_t buf[2048]; + +extern void putch(uint8_t ch); + +/* Uses the above routine to output a string... */ +void puts(const uint8_t *text) +{ + int32_t i; + + for (i = 0; i < strlen((const int8_t *)text); i++) { + putch(text[i]); + } +} + +void printk(const char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = vsprintf(buf, (const int8_t *)format, args); + va_end(args); + + puts((const uint8_t *)buf); +} + diff --git a/ports/mips/printk.h b/ports/mips/printk.h new file mode 100644 index 0000000..eeee752 --- /dev/null +++ b/ports/mips/printk.h @@ -0,0 +1,43 @@ +/* + * This file is part of Freax kernel. + * + * Copyright (c) Himanshu Chauhan 2009-10. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H +#define _PRINTK_H + +#include +#include + +extern void putch (uint8_t *ch); +extern void puts (const uint8_t *text); +extern void printk (const char*format, ...); + +#endif diff --git a/ports/mips/stdarg.h b/ports/mips/stdarg.h new file mode 100755 index 0000000..fd79ec0 --- /dev/null +++ b/ports/mips/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/ports/mips/string.c b/ports/mips/string.c new file mode 100644 index 0000000..bd65a10 --- /dev/null +++ b/ports/mips/string.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +void *memcpy(void *dest, const void *src, size_t count) +{ + const int8_t *sp = (const int8_t *)src; + int8_t *dp = (int8_t *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, int8_t val, size_t count) +{ + int8_t *temp = (int8_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) +{ + uint16_t *temp = (uint16_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +size_t strlen(const int8_t *str) +{ + size_t retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} diff --git a/ports/mips/string.h b/ports/mips/string.h new file mode 100644 index 0000000..ed5f98a --- /dev/null +++ b/ports/mips/string.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H +#define __STRING_H + +#include + +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *dest, int8_t val, size_t count); +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); +size_t strlen(const int8_t *str); + +#endif /* __STRING_H */ + diff --git a/ports/mips/system.h b/ports/mips/system.h new file mode 100644 index 0000000..c655830 --- /dev/null +++ b/ports/mips/system.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H +#define _SYSTEM_H + +#include +#include + +extern const uint8_t *kernel_name; +extern const uint8_t *kernel_version; +extern const uint8_t *kernel_bdate; +extern const uint8_t *kernel_btime; + +extern void *memcpy (void *dest, const void *src, size_t count); +extern void *memset (void *dest, int8_t val, size_t count); +extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); +extern size_t strlen (const int8_t *str); +extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); +extern void init_console (void); +extern int32_t arch_init (void); +extern uint8_t ioreadb (void *addr); +extern void iowriteb (void *addr, uint8_t data); + +#endif /* _SYSTEM_H */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 0ab9a94..af05049 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Kelvin Lawson. All rights reserved. + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +31,8 @@ #include "atomport-private.h" #include "atomtests.h" #include "atomtimer.h" +#include "system.h" +#include "printk.h" /* Constants */ @@ -124,14 +126,9 @@ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; /* Idle thread's stack area */ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; -/* STDIO stream */ -static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); - - /* Forward declarations */ static void main_thread_func (uint32_t data); - /** * \b main * @@ -145,12 +142,6 @@ int main ( void ) { int8_t status; - /** - * Reuse part of the idle thread's stack for the stack required - * during this startup function. - */ - SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1]; - /** * Note: to protect OS structures and data during initialisation, * interrupts must remain disabled until the first thread @@ -172,11 +163,11 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], + (IDLE_STACK_SIZE_BYTES/2)); if (status == ATOM_OK) { - /* Enable the system tick timer */ - avrInitSystemTickTimer(); + /* FIXME: Enable the system tick timer */ /* Create an application thread */ status = atomThreadCreate(&main_tcb, @@ -221,77 +212,14 @@ int main ( void ) static void main_thread_func (uint32_t data) { uint32_t test_status; - int sleep_ticks; - /* Enable all LEDs (STK500-specific) */ - DDRB = 0xFF; - PORTB = 0xFF; - - /* Initialise UART (9600bps) */ - if (uart_init(9600) != 0) - { - /* Error initialising UART */ - } - - /** - * Redirect stdout via the UART. Note that the UART write routine - * is protected via a semaphore, so the OS must be started before - * use of the UART. - */ - stdout = &uart_stdout; + init_console(); /* Put a message out on the UART */ - printf_P(PSTR("Go\n")); + printk("Main Thread\n"); /* Start test. All tests use the same start API. */ test_status = test_start(); - /* Check main thread stack usage (if enabled) */ -#ifdef ATOM_STACK_CHECKING - if (test_status == 0) - { - uint32_t used_bytes, free_bytes; - - /* Check idle thread stack usage */ - if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) - { - /* Check the thread did not use up to the end of stack */ - if (free_bytes == 0) - { - printf_P (PSTR("Main stack overflow\n")); - test_status++; - } - - /* Log the stack usage */ -#ifdef TESTS_LOG_STACK_USAGE - printf_P (PSTR("MainUse:%d\n"), used_bytes); -#endif - } - - } -#endif - - /* Log final status */ - if (test_status == 0) - { - printf_P (PSTR("Pass\n")); - } - else - { - printf_P (PSTR("Fail(%d)\n"), test_status); - } - - /* Flash LED once per second if passed, very quickly if failed */ - sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8); - - /* Test finished, flash slowly for pass, fast for fail */ - while (1) - { - /* Toggle a LED (STK500-specific) */ - PORTB ^= (1 << 7); - - /* Sleep then toggle LED again */ - atomTimerDelay(sleep_ticks); - } - + while(1); } diff --git a/ports/mips/vsprintf.c b/ports/mips/vsprintf.c new file mode 100644 index 0000000..a957676 --- /dev/null +++ b/ports/mips/vsprintf.c @@ -0,0 +1,244 @@ +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + * and Himanshu Fucked it up further for Freax :)) + */ + +#include +#include +#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const int8_t **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +/*#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; })*/ + +static uint32_t do_div (int32_t *n, int32_t base) +{ + uint32_t remainder = *n % base; + *n /= base; + return remainder; +} + +static int8_t * number(int8_t * str, int num, int32_t base, + int32_t size, int32_t precision, int32_t type) +{ + int8_t c,sign,tmp[36]; + const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int32_t i; + + if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; + if (type & LEFT) type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type & SIGN && num < 0) { + sign = '-'; + num = -num; + } else + sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); + if (sign) size--; + + if (type & SPECIAL) { + if (base == 16) { + size -= 2; + } else if (base == 8) { + size--; + } + } + + i = 0; + if (num == 0) + tmp[i++] = '0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while(size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) { + *str++ = '0'; + } else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while(size-- > 0) + *str++ = c; + while(i < precision--) + *str++ = '0'; + while(i-- > 0) + *str++ = tmp[i]; + while(size-- > 0) + *str++ = ' '; + return str; +} + +int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args) +{ + int32_t len; + int32_t i; + int8_t * str; + int8_t *s; + int32_t *ip; + + int32_t flags; /* flags to number() */ + + int32_t field_width; /* width of output field */ + int32_t precision; /* min. # of digits for integers; max + number of chars for from string */ + int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, int8_t *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int32_t *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} diff --git a/tests/kern1.c b/tests/kern1.c index 1695039..c467298 100644 --- a/tests/kern1.c +++ b/tests/kern1.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomtests.h" diff --git a/tests/kern2.c b/tests/kern2.c index 7387c89..d1d1254 100644 --- a/tests/kern2.c +++ b/tests/kern2.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /** * \b test_start diff --git a/tests/kern3.c b/tests/kern3.c index 20304f8..555ac8e 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/kern4.c b/tests/kern4.c index 909232e..eb39364 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 diff --git a/tests/mutex1.c b/tests/mutex1.c index e3bc16a..a2b03e7 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -27,12 +27,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atommutex.h" #include "atomtests.h" - /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/mutex2.c b/tests/mutex2.c index 9725f44..7e90d22 100644 --- a/tests/mutex2.c +++ b/tests/mutex2.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex3.c b/tests/mutex3.c index f604430..7a9b2da 100644 --- a/tests/mutex3.c +++ b/tests/mutex3.c @@ -32,6 +32,9 @@ #include "atomtests.h" #include "atommutex.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 @@ -288,4 +291,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex4.c b/tests/mutex4.c index b478517..28553fd 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" @@ -293,4 +299,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex5.c b/tests/mutex5.c index 9aa18f2..c8dff89 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" @@ -299,4 +305,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex6.c b/tests/mutex6.c index ca2c2d6..79bcd50 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -27,6 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif + #include "atom.h" #include "atomtests.h" @@ -290,4 +297,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex7.c b/tests/mutex7.c index 9189dee..e9edcb6 100644 --- a/tests/mutex7.c +++ b/tests/mutex7.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex8.c b/tests/mutex8.c index 14febb9..fc3e62a 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atommutex.h" diff --git a/tests/mutex9.c b/tests/mutex9.c index e509762..394e1a7 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue1.c b/tests/queue1.c index f3a8938..50089c6 100644 --- a/tests/queue1.c +++ b/tests/queue1.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue10.c b/tests/queue10.c index ca6b6be..7a8187c 100644 --- a/tests/queue10.c +++ b/tests/queue10.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue2.c b/tests/queue2.c index 8528ade..0365882 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue3.c b/tests/queue3.c index 277a4e3..d2ea0e1 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue4.c b/tests/queue4.c index 3420882..46703d4 100644 --- a/tests/queue4.c +++ b/tests/queue4.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue5.c b/tests/queue5.c index bf07960..e7832cb 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue6.c b/tests/queue6.c index 4de62f0..c2d3473 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue7.c b/tests/queue7.c index 5b249d8..ab77781 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue8.c b/tests/queue8.c index 9064e47..78921f8 100644 --- a/tests/queue8.c +++ b/tests/queue8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue9.c b/tests/queue9.c index 1bc1034..78f1132 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem1.c b/tests/sem1.c index b7b6335..69623eb 100644 --- a/tests/sem1.c +++ b/tests/sem1.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtests.h" diff --git a/tests/sem2.c b/tests/sem2.c index b83f8cf..d7f0e40 100644 --- a/tests/sem2.c +++ b/tests/sem2.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtests.h" @@ -321,4 +326,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/sem3.c b/tests/sem3.c index 6648b39..113166f 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem4.c b/tests/sem4.c index 419195c..5fb0eb9 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem5.c b/tests/sem5.c index dc87f9f..a7e4f6d 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem6.c b/tests/sem6.c index 851f9b8..106bbfa 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem7.c b/tests/sem7.c index 62fa16f..b4595cb 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem8.c b/tests/sem8.c index 432cf32..75d4896 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem9.c b/tests/sem9.c index d7a86d6..48f5249 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/timer1.c b/tests/timer1.c index 2e2d940..d1bbf39 100644 --- a/tests/timer1.c +++ b/tests/timer1.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -246,4 +251,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/timer2.c b/tests/timer2.c index a606830..b645f0e 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" diff --git a/tests/timer3.c b/tests/timer3.c index 0ea7a50..e6f9104 100644 --- a/tests/timer3.c +++ b/tests/timer3.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -240,4 +245,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/timer4.c b/tests/timer4.c index 1e74e88..f2864c6 100644 --- a/tests/timer4.c +++ b/tests/timer4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" @@ -190,4 +196,4 @@ static void testCallback (POINTER cb_data) /* Not called at expected time, don't clear the location */ } -} \ No newline at end of file +} diff --git a/tests/timer5.c b/tests/timer5.c index 02ca33c..acf56b1 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -27,8 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ - +#ifndef STAND_ALONE #include +#else +#include +#include +#endif + #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -138,4 +143,4 @@ static void testCallback (POINTER cb_data) { /* Callback was called */ callback_ran_flag = TRUE; -} \ No newline at end of file +} diff --git a/tests/timer6.c b/tests/timer6.c index da7f0da..bb50abf 100644 --- a/tests/timer6.c +++ b/tests/timer6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" @@ -152,4 +158,4 @@ static void testCallback (POINTER cb_data) { /* Callback was called */ *(int *)cb_data = TRUE; -} \ No newline at end of file +} diff --git a/tests/timer7.c b/tests/timer7.c index d2a7e54..2e10731 100644 --- a/tests/timer7.c +++ b/tests/timer7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" From 8688d0eee08145c6e448b1261a3097242048b0ab Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Fri, 20 May 2011 09:22:05 +0530 Subject: [PATCH 03/76] Half way debug code of context switching. Main thread comes up but the secondary threads doesn't get scheduled. Signed-off-by: Himanshu Chauhan --- kernel/atom.h | 2 +- kernel/atomkernel.c | 2 +- ports/mips/8250-serial.c | 9 ++-- ports/mips/Makefile | 2 +- ports/mips/atomport-asm.s | 63 +++++++++++++++---------- ports/mips/atomport-entry.s | 52 ++++++++++++-------- ports/mips/atomport-interrupts.c | 58 +++++++++++++++++++++++ ports/mips/atomport-interrupts.h | 38 +++++++++++++++ ports/mips/atomport-timer.c | 67 ++++++++++++++++++++++++++ ports/mips/atomport-timer.h | 37 +++++++++++++++ ports/mips/atomport.c | 27 ++++++----- ports/mips/atomport.h | 4 +- ports/mips/tests-main.c | 81 +++++++++++++++++++------------- 13 files changed, 341 insertions(+), 101 deletions(-) create mode 100644 ports/mips/atomport-interrupts.c create mode 100644 ports/mips/atomport-interrupts.h create mode 100644 ports/mips/atomport-timer.c create mode 100644 ports/mips/atomport-timer.h diff --git a/kernel/atom.h b/kernel/atom.h index 43c3734..870e8bb 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -116,7 +116,7 @@ extern ATOM_TCB *atomCurrentContext (void); extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); -extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); +extern ATOM_TCB *archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); extern void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param); extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 6952576..d994e2e 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -348,7 +348,7 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) curr_tcb = new_tcb; /* Call the architecture-specific context switch */ - archContextSwitch (old_tcb, new_tcb); + old_tcb = archContextSwitch (old_tcb, new_tcb); } /** diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c index a7a3f59..b1b2227 100644 --- a/ports/mips/8250-serial.c +++ b/ports/mips/8250-serial.c @@ -34,10 +34,11 @@ #include #include <8250-serial.h> -#define PORT1 (void *)0x140003f8 -#define PORT2 (void *)0x140002F8 -#define PORT3 (void *)0x140003E8 -#define PORT4 (void *)0x140002E8 +//#define PORT1 (void *)0x140003f8 +//#define PORT2 (void *)0x140002F8 +//#define PORT3 (void *)0x140003E8 +//#define PORT4 (void *)0x140002E8 +#define PORT1 (void *)0xc00003f8 static inline unsigned int serial_in(int offset) { diff --git a/ports/mips/Makefile b/ports/mips/Makefile index dc90cdf..aae07df 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -42,7 +42,7 @@ endif BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o atomport-interrupts.o atomport-timer.o APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index b9c9cd3..ce6adf9 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -27,7 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include .section .text @@ -40,34 +40,44 @@ */ .globl archContextSwitch archContextSwitch: + move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + sw s0, (s0_IDX * 4)(k0) + sw s1, (s1_IDX * 4)(k0) + sw s2, (s2_IDX * 4)(k0) + sw s3, (s3_IDX * 4)(k0) + sw s4, (s4_IDX * 4)(k0) + sw s5, (s5_IDX * 4)(k0) + sw s6, (s6_IDX * 4)(k0) + sw s7, (s7_IDX * 4)(k0) + sw s8, (s8_IDX * 4)(k0) + sw sp, (sp_IDX * 4)(k0) + sw gp, (gp_IDX * 4)(k0) + mfc0 k1, CP0_EPC + nop + nop + nop + sw k1, (ra_IDX * 4)(k0) + lw k1, 0(a1) + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop - sw s0, (s0_IDX * 4)(a0) - sw s1, (s1_IDX * 4)(a0) - sw s2, (s2_IDX * 4)(a0) - sw s3, (s3_IDX * 4)(a0) - sw s4, (s4_IDX * 4)(a0) - sw s5, (s5_IDX * 4)(a0) - sw s6, (s6_IDX * 4)(a0) - sw s7, (s7_IDX * 4)(a0) - sw s8, (s8_IDX * 4)(a0) - sw sp, (sp_IDX * 4)(a0) - sw gp, (gp_IDX * 4)(a0) - - lw s0, (s0_IDX * 4)(a1) - lw s1, (s1_IDX * 4)(a1) - lw s2, (s2_IDX * 4)(a1) - lw s3, (s3_IDX * 4)(a1) - lw s4, (s4_IDX * 4)(a1) - lw s5, (s5_IDX * 4)(a1) - lw s6, (s6_IDX * 4)(a1) - lw s7, (s7_IDX * 4)(a1) - lw s8, (s8_IDX * 4)(a1) - lw sp, (sp_IDX * 4)(a1) - lw gp, (gp_IDX * 4)(a1) - - j ra + jr ra nop /** @@ -94,4 +104,5 @@ archFirstThreadRestore: nop nop nop + enable_global_interrupts eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index 508ea5d..d121f9b 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -51,6 +51,11 @@ LEAF(_start) mtc0 zero, CP0_COMPARE mtc0 zero, CP0_COUNT + li a0, 0xC0000000 /* FIXME: Remove these two hard codings */ + li a1, 0x14000000 + bal create_tlb_entry + move zero, a2 + la sp, _stack_start /* setup the stack (bss segment) */ la t0, main j t0 /* Call the C- code now */ @@ -59,31 +64,38 @@ LEAF(_start) 1: b 1b /* we should not come here whatsoever */ END(_start) -.extern vmm_cpu_handle_pagefault - LEAF(_handle_tlbmiss) - //disable_global_interrupts - //move k0, sp - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal vmm_cpu_handle_pagefault - //nop - //enable_global_interrupts - //eret +#if 0 + disable_global_interrupts + move k0, sp + SAVE_INT_CONTEXT(_int_stack) + move a0, sp + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +#else + b _handle_tlbmiss + nop +#endif END(_handle_tlbmiss) -.extern generic_int_handler +.extern handle_mips_systick .extern _int_stack -.extern vmm_regs_dump LEAF(_handle_interrupt) - //disable_global_interrupts - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal generic_int_handler - //nop - //RESTORE_INT_CONTEXT(sp) - //enable_global_interrupts - //eret + disable_global_interrupts + mfc0 k0, CP0_CAUSE + lui k1, 0x4000 + and k0, k1, k0 + beq k0, zero, 1f + nop + move k0, sp + la sp, _int_stack + bal handle_mips_systick + nop +1: + enable_global_interrupts + eret END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c new file mode 100644 index 0000000..970181f --- /dev/null +++ b/ports/mips/atomport-interrupts.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +void mips_setup_interrupts() +{ + uint32_t ebase = read_c0_ebase(); + ebase &= ~0x3FFF000UL; + write_c0_ebase(ebase); + + uint32_t sr = read_c0_status(); + sr &= ~(0x01UL << 22); + sr &= ~(0x3UL << 1); + write_c0_status(sr); + + uint32_t cause = read_c0_status(); + cause |= 0x01UL << 23; + write_c0_cause(cause); +} + +void mips_enable_global_interrupts(void) +{ + __asm__ __volatile__ ("ei $0\t\n"); +} + +void mips_disable_global_interrupts(void) +{ + __asm__ __volatile__("di $0\t\n"); +} diff --git a/ports/mips/atomport-interrupts.h b/ports/mips/atomport-interrupts.h new file mode 100644 index 0000000..41200de --- /dev/null +++ b/ports/mips/atomport-interrupts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_INTERRUPTS_H +#define __ATOMPORT_INTERRUPTS_H + +void mips_setup_interrupts(); +void mips_enable_global_interrupts(void); +void mips_disable_global_interrupts(void); +void handle_mips_systick(void); + +#endif /* __ATOMPORT_INTERRUPTS_H */ diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c new file mode 100644 index 0000000..9ed1889 --- /dev/null +++ b/ports/mips/atomport-timer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +/** CPU frequency in MHz */ +#define CPU_FREQ_MHZ 100 + +/** Number of counter counter should increase to get required ticks */ +#define COUNTER_TICK_COUNT ((1000000 * SYSTEM_TICKS_PER_SEC) / CPU_FREQ_MHZ) + +unsigned long long jiffies; + +void mips_cpu_timer_enable(void) +{ + uint32_t sr = read_c0_status(); + sr |= ((0x1UL << 7) << 8); + write_c0_status(sr); + + uint32_t cause = read_c0_cause(); + cause &= ~(0x1UL << 27); + write_c0_cause(cause); + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} + +void handle_mips_systick(void) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} diff --git a/ports/mips/atomport-timer.h b/ports/mips/atomport-timer.h new file mode 100644 index 0000000..b95dd7b --- /dev/null +++ b/ports/mips/atomport-timer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TIMER_H +#define __ATOM_PORT_TIMER_H + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +void mips_cpu_timer_enable(void); + +#endif /* __ATOM_PORT_TIMER_H */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index 4b77a20..e3c7dcd 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -31,6 +31,7 @@ #include #include #include +#include /** * This function initialises each thread's stack during creation, before the @@ -56,20 +57,20 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS)); + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_REGISTERS)); - tcb_ptr->sp_save_ptr = stack_start; + tcb_ptr->sp_save_ptr = (void *)stack_start; - STORE_VAL(stack_start, sp, stack_start); - STORE_VAL(stack_start, s8, stack_start); - STORE_VAL(stack_start, s1, 0); - STORE_VAL(stack_start, s2, 0); - STORE_VAL(stack_start, s3, 0); - STORE_VAL(stack_start, s4, 0); - STORE_VAL(stack_start, s5, 0); - STORE_VAL(stack_start, s6, 0); - STORE_VAL(stack_start, s7, 0); - STORE_VAL(stack_start, ra, entry_point); - STORE_VAL(stack_start, a0, entry_param); + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 9a20931..1f95356 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -31,9 +31,7 @@ #define __ATOM_PORT_H #include "atomport-types.h" - -/* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 100 +#include "atomport-timer.h" /** * Architecture-specific types. diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index af05049..0deb23d 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -33,6 +33,7 @@ #include "atomtimer.h" #include "system.h" #include "printk.h" +#include "atomport-interrupts.h" /* Constants */ @@ -47,7 +48,7 @@ * In this case, the idle stack is allocated on the BSS via the * idle_thread_stack[] byte array. */ -#define IDLE_STACK_SIZE_BYTES 128 +#define IDLE_STACK_SIZE_BYTES 4096 /* @@ -73,7 +74,7 @@ * future as the codebase changes but for the time being is enough to * cope with all of the automated tests. */ -#define MAIN_STACK_SIZE_BYTES 204 +#define MAIN_STACK_SIZE_BYTES 8192 /* @@ -119,15 +120,19 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; +static ATOM_TCB secondary_tcb; /* Main thread's stack area */ -static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Idle thread's stack area */ -static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); + +static uint8_t secondary_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Forward declarations */ static void main_thread_func (uint32_t data); +static void secondary_thread_func (uint32_t data); /** * \b main @@ -163,35 +168,45 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], - (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES], + IDLE_STACK_SIZE_BYTES); if (status == ATOM_OK) { /* FIXME: Enable the system tick timer */ + mips_setup_interrupts(); + init_console(); /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], + &main_thread_stack[MAIN_STACK_SIZE_BYTES], MAIN_STACK_SIZE_BYTES); if (status == ATOM_OK) { - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + status = atomThreadCreate(&secondary_tcb, TEST_THREAD_PRIO, + secondary_thread_func, 0, + &secondary_thread_stack[MAIN_STACK_SIZE_BYTES], + MAIN_STACK_SIZE_BYTES); + + if (status == ATOM_OK) { + mips_cpu_timer_enable(); + + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } } - while (1) - ; + while (1); /* There was an error starting the OS if we reach here */ return (0); @@ -211,15 +226,17 @@ int main ( void ) */ static void main_thread_func (uint32_t data) { - uint32_t test_status; - - init_console(); - - /* Put a message out on the UART */ - printk("Main Thread\n"); - - /* Start test. All tests use the same start API. */ - test_status = test_start(); - - while(1); + while (1) { + /* Put a message out on the UART */ + printk("Main Thread\n"); + atomTimerDelay(SYSTEM_TICKS_PER_SEC); + } +} + +static void secondary_thread_func (uint32_t data) +{ + while (1) { + printk("Secondary Thread\n"); + atomTimerDelay (SYSTEM_TICKS_PER_SEC); + } } From c091aabec05b4fa18cdf0364bad1254206840356 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Wed, 25 May 2011 22:31:13 +0530 Subject: [PATCH 04/76] Atomthreads working on MIPS (Qemu MIPS Machine). Signed-off-by: Himanshu Chauhan --- kernel/atomkernel.c | 1 + ports/mips/.gdbinit | 1 + ports/mips/atomport-asm-macros.h | 84 +++++++++--------- ports/mips/atomport-asm.s | 88 ++++++++++++++++--- ports/mips/atomport-entry.s | 22 ++++- ports/mips/atomport-private.h | 141 ++++++++++++++++--------------- ports/mips/atomport.c | 3 +- ports/mips/atomport.h | 19 ++++- 8 files changed, 231 insertions(+), 128 deletions(-) create mode 100644 ports/mips/.gdbinit diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index d994e2e..4b53af1 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -147,6 +147,7 @@ #include #else #include +#include #endif #include "atom.h" diff --git a/ports/mips/.gdbinit b/ports/mips/.gdbinit new file mode 100644 index 0000000..24efe1e --- /dev/null +++ b/ports/mips/.gdbinit @@ -0,0 +1 @@ +target remote localhost:1234 diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h index c71f1e1..d73e9c7 100644 --- a/ports/mips/atomport-asm-macros.h +++ b/ports/mips/atomport-asm-macros.h @@ -63,17 +63,9 @@ _name: \ #define LOAD_REG(reg, treg) \ lw reg, ((reg ## _IDX) * 4)(treg) -#define SAVE_INT_CONTEXT(_int_sp) \ - move k0, sp; \ - la sp, _int_sp; \ - addiu sp, sp, -((CPU_USER_REG_COUNT + 1)* 4); \ +#define SAVE_INT_CONTEXT \ + addiu sp, sp, -((NUM_REGISTERS + 1)* 4); \ mfc0 k1, CP0_EPC; \ - SAVE_REG(v0,sp); \ - SAVE_REG(v1,sp); \ - SAVE_REG(a0,sp); \ - SAVE_REG(a1,sp); \ - SAVE_REG(a2,sp); \ - SAVE_REG(a3,sp); \ SAVE_REG(t0,sp); \ SAVE_REG(t1,sp); \ SAVE_REG(t2,sp); \ @@ -82,6 +74,14 @@ _name: \ SAVE_REG(t5,sp); \ SAVE_REG(t6,sp); \ SAVE_REG(t7,sp); \ + SAVE_REG(t8,sp); \ + SAVE_REG(t9,sp); \ + SAVE_REG(v0,sp); \ + SAVE_REG(v1,sp); \ + SAVE_REG(a0,sp); \ + SAVE_REG(a1,sp); \ + SAVE_REG(a2,sp); \ + SAVE_REG(a3,sp); \ SAVE_REG(s0,sp); \ SAVE_REG(s1,sp); \ SAVE_REG(s2,sp); \ @@ -90,45 +90,43 @@ _name: \ SAVE_REG(s5,sp); \ SAVE_REG(s6,sp); \ SAVE_REG(s7,sp); \ - SAVE_REG(t8,sp); \ - SAVE_REG(t9,sp); \ SAVE_REG(gp,sp); \ SAVE_REG(s8,sp); \ SAVE_REG(ra,sp); \ sw k0, (sp_IDX * 4)(sp); \ - sw k1, (CPU_USER_REG_COUNT * 4)(sp); + sw k1, (NUM_REGISTERS * 4)(sp); -#define RESTORE_INT_CONTEXT(treg) \ - lw k1, (CPU_USER_REG_COUNT * 4)(treg); \ +#define RESTORE_INT_CONTEXT \ + lw k1, (NUM_REGISTERS * 4)(sp); \ mtc0 k1, CP0_EPC; \ - LOAD_REG(v0,treg); \ - LOAD_REG(v1,treg); \ - LOAD_REG(a0,treg); \ - LOAD_REG(a1,treg); \ - LOAD_REG(a2,treg); \ - LOAD_REG(a3,treg); \ - LOAD_REG(t0,treg); \ - LOAD_REG(t1,treg); \ - LOAD_REG(t2,treg); \ - LOAD_REG(t3,treg); \ - LOAD_REG(t4,treg); \ - LOAD_REG(t5,treg); \ - LOAD_REG(t6,treg); \ - LOAD_REG(t7,treg); \ - LOAD_REG(s0,treg); \ - LOAD_REG(s1,treg); \ - LOAD_REG(s2,treg); \ - LOAD_REG(s3,treg); \ - LOAD_REG(s4,treg); \ - LOAD_REG(s5,treg); \ - LOAD_REG(s6,treg); \ - LOAD_REG(s7,treg); \ - LOAD_REG(t8,treg); \ - LOAD_REG(t9,treg); \ - LOAD_REG(gp,treg); \ - LOAD_REG(ra,treg); \ - LOAD_REG(s8,treg); \ - lw sp, (sp_IDX * 4)(treg); + LOAD_REG(s0,sp); \ + LOAD_REG(s1,sp); \ + LOAD_REG(s2,sp); \ + LOAD_REG(s3,sp); \ + LOAD_REG(s4,sp); \ + LOAD_REG(s5,sp); \ + LOAD_REG(s6,sp); \ + LOAD_REG(s7,sp); \ + LOAD_REG(v0,sp); \ + LOAD_REG(v1,sp); \ + LOAD_REG(a0,sp); \ + LOAD_REG(a1,sp); \ + LOAD_REG(a2,sp); \ + LOAD_REG(a3,sp); \ + LOAD_REG(t0,sp); \ + LOAD_REG(t1,sp); \ + LOAD_REG(t2,sp); \ + LOAD_REG(t3,sp); \ + LOAD_REG(t4,sp); \ + LOAD_REG(t5,sp); \ + LOAD_REG(t6,sp); \ + LOAD_REG(t7,sp); \ + LOAD_REG(t8,sp); \ + LOAD_REG(t9,sp); \ + LOAD_REG(gp,sp); \ + LOAD_REG(ra,sp); \ + LOAD_REG(s8,sp); \ + lw sp, (sp_IDX * 4)(sp); #endif /* __ASSEMBLY__ */ diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index ce6adf9..53cff5b 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -31,6 +31,7 @@ .section .text +.extern atomCurrentContext /** * Function that performs the contextSwitch. Whether its a voluntary release * of CPU by thread or a pre-emption, under both conditions this function is @@ -40,6 +41,18 @@ */ .globl archContextSwitch archContextSwitch: + /* + * Check if we are being called in interrupt + * context. If yes, we need to restore complete + * context and return directly from here. + */ + move k0, ra + bal atomCurrentContext + nop + beq v0, zero, __in_int_context + nop + + move ra, k0 move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ sw s0, (s0_IDX * 4)(k0) @@ -53,13 +66,22 @@ archContextSwitch: sw s8, (s8_IDX * 4)(k0) sw sp, (sp_IDX * 4)(k0) sw gp, (gp_IDX * 4)(k0) - mfc0 k1, CP0_EPC - nop - nop - nop - sw k1, (ra_IDX * 4)(k0) + sw ra, (ra_IDX * 4)(k0) + /* + * We are saving registers in non-interrupt context because + * a thread probably is trying to yield CPU. Storing zero + * in EPC offset differentiates this. When restoring the + * context, if EPC offset has zero we will restore only + * the partial context. Rest will be done by GCC while + * unwinding the call. + */ + sw zero, (cp0_epc_IDX * 4)(k0) lw k1, 0(a1) + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + lw s0, (s0_IDX * 4)(k1) lw s1, (s1_IDX * 4)(k1) lw s2, (s2_IDX * 4)(k1) @@ -71,15 +93,61 @@ archContextSwitch: lw s8, (s8_IDX * 4)(k1) lw sp, (sp_IDX * 4)(k1) lw gp, (gp_IDX * 4)(k1) - lw k0, (ra_IDX * 4)(k1) - mtc0 k0, CP0_EPC - nop - nop - nop + lw ra, (ra_IDX * 4)(k1) jr ra nop +__in_int_context: + move ra, k0 + /* + * In interrupt context, the interrupt handler + * saves the context for us. Its very well there + * and we don't need to do it again. + * + * We will figure out of the task that we are + * switching in was saved in interrupt context + * or otherwise. + */ + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + + /* + * Unwinding a task switched in non-interrupt context. + * So, restore only the partials. But since we are in + * interrupt mode, we will put ra in epc and do a eret + * so that we get out of interrupt mode and switch to + * the new task. + */ +__unwind_non_int_context: + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw ra, (ra_IDX * 4)(k1) + mtc0 ra, CP0_EPC + nop + nop + nop + j __ret_from_switch + nop + +__unwind_int_context: + move sp, k1 + RESTORE_INT_CONTEXT + +__ret_from_switch: + enable_global_interrupts + eret + /** * archFirstThreadRestore(ATOM_TCB *new_tcb) * diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index d121f9b..35b5735 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -89,13 +89,33 @@ LEAF(_handle_interrupt) and k0, k1, k0 beq k0, zero, 1f nop + + move k0, ra + move k1, v0 + bal atomCurrentContext + nop + beq v0, zero, 2f /* v0 should be current context */ + nop + + move ra, k0 + lw k0, 0(v0) + move v0, k1 + move k1, k0 + /* + * Note that we aren't loading any new SP. Context + * will be save on the interrupted threads' stack. + */ move k0, sp - la sp, _int_stack + move sp, k1 + SAVE_INT_CONTEXT bal handle_mips_systick nop + RESTORE_INT_CONTEXT 1: enable_global_interrupts eret + +2: b 2b END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h index e2af7e0..282dbb1 100644 --- a/ports/mips/atomport-private.h +++ b/ports/mips/atomport-private.h @@ -67,76 +67,77 @@ #define NUM_REGISTERS 32 #define WORD_SIZE 4 -#define v0_IDX 0 -#define v1_IDX 1 -#define a0_IDX 2 -#define a1_IDX 3 -#define a2_IDX 4 -#define a3_IDX 5 -#define t0_IDX 6 -#define t1_IDX 7 -#define t2_IDX 8 -#define t3_IDX 9 -#define t4_IDX 10 -#define t5_IDX 11 -#define t6_IDX 12 -#define t7_IDX 13 -#define s0_IDX 14 -#define s1_IDX 15 -#define s2_IDX 16 -#define s3_IDX 17 -#define s4_IDX 18 -#define s5_IDX 19 -#define s6_IDX 20 -#define s7_IDX 21 -#define t8_IDX 22 -#define t9_IDX 23 -#define sp_IDX 24 -#define gp_IDX 25 -#define s8_IDX 26 -#define ra_IDX 27 -#define k0_IDX 28 -#define k1_IDX 29 -#define at_IDX 30 -#define zero_IDX 31 +#define v0_IDX 0 +#define v1_IDX 1 +#define a0_IDX 2 +#define a1_IDX 3 +#define a2_IDX 4 +#define a3_IDX 5 +#define t0_IDX 6 +#define t1_IDX 7 +#define t2_IDX 8 +#define t3_IDX 9 +#define t4_IDX 10 +#define t5_IDX 11 +#define t6_IDX 12 +#define t7_IDX 13 +#define s0_IDX 14 +#define s1_IDX 15 +#define s2_IDX 16 +#define s3_IDX 17 +#define s4_IDX 18 +#define s5_IDX 19 +#define s6_IDX 20 +#define s7_IDX 21 +#define t8_IDX 22 +#define t9_IDX 23 +#define sp_IDX 24 +#define gp_IDX 25 +#define s8_IDX 26 +#define ra_IDX 27 +#define k0_IDX 28 +#define k1_IDX 29 +#define at_IDX 30 +#define zero_IDX 31 +#define cp0_epc_IDX 32 -#define CP0_INDEX $0 -#define CP0_RANDOM $1 -#define CP0_ENTRYLO0 $2 -#define CP0_ENTRYLO1 $3 -#define CP0_CONTEXT $4 -#define CP0_PAGEMASK $5 -#define CP0_WIRED $6 -#define CP0_HWRENA $7 -#define CP0_BADVADDR $8 -#define CP0_COUNT $9 -#define CP0_ENTRYHI $10 -#define CP0_COMPARE $11 -#define CP0_STATUS $12 -#define CP0_INTCTL $12,1 -#define CP0_SRSCTL $12,2 -#define CP0_SRSMAP $12,3 -#define CP0_CAUSE $13 -#define CP0_EPC $14 -#define CP0_PRID $15 -#define CP0_EBASE $15,1 -#define CP0_CONFIG $16 -#define CP0_CONFIG1 $16,1 -#define CP0_CONFIG2 $16,2 -#define CP0_CONFIG3 $16,3 -#define CP0_LLADDR $17 -#define CP0_WATCHLO $18 -#define CP0_WATCHHI $19 -#define CP0_DEBUG $23 -#define CP0_DEPC $24 -#define CP0_PERFCTL $25,0 -#define CP0_PERFCNT $25,1 -#define CP0_ECC $26 -#define CP0_CACHEERR $27 -#define CP0_TAGLO $28 -#define CP0_DATALO $28,1 -#define CP0_TAGHI $29 -#define CP0_DATAHI $29,1 -#define CP0_ERRORPC $30 +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_HWRENA $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_INTCTL $12,1 +#define CP0_SRSCTL $12,2 +#define CP0_SRSMAP $12,3 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_EBASE $15,1 +#define CP0_CONFIG $16 +#define CP0_CONFIG1 $16,1 +#define CP0_CONFIG2 $16,2 +#define CP0_CONFIG3 $16,3 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFCTL $25,0 +#define CP0_PERFCNT $25,1 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_DATALO $28,1 +#define CP0_TAGHI $29 +#define CP0_DATAHI $29,1 +#define CP0_ERRORPC $30 #endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index e3c7dcd..0509263 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -57,7 +57,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_REGISTERS)); + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * (NUM_REGISTERS + 1))); tcb_ptr->sp_save_ptr = (void *)stack_start; @@ -70,6 +70,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, STORE_VAL(stack_start, s5, 0); STORE_VAL(stack_start, s6, 0); STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, cp0_epc, entry_point); STORE_VAL(stack_start, ra, entry_point); STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 1f95356..0df03eb 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -41,9 +41,22 @@ #define POINTER void * /* Critical region protection */ -#define CRITICAL_STORE -#define CRITICAL_START() __asm__ __volatile__("di $0\n\t") -#define CRITICAL_END() __asm__ __volatile__("ei $0\n\t"); +#define CRITICAL_STORE unsigned int status_reg +#define CRITICAL_START() \ + __asm__ __volatile__("di %0\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ehb\t\n" \ + :"=r"(status_reg)); + +#define CRITICAL_END() \ + __asm__ __volatile__("ei %0\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ehb\t\n" \ + ::"r"(status_reg)); /* Uncomment to enable stack-checking */ /* #define ATOM_STACK_CHECKING */ From 8b1739e8f431edbe877f67a178b4b679f8c43201 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:00:21 +0100 Subject: [PATCH 05/76] STM8: Remove deprecated stack reference. --- ports/stm8/tests-main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index bf83ee6..460c4bc 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -95,10 +95,6 @@ */ -/* Linker-provided startup stack location (usually top of RAM) */ -extern int _stack; - - /* Local data */ /* Application threads' TCBs */ From 89f877501152c6679809fa6eaa3a37028c6685cd Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:49:44 +0100 Subject: [PATCH 06/76] Use new build-cosmic output directory for Cosmic build objects. --- ports/stm8/atomthreads.lkf | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ports/stm8/atomthreads.lkf b/ports/stm8/atomthreads.lkf index 1c2ada1..44e02bb 100644 --- a/ports/stm8/atomthreads.lkf +++ b/ports/stm8/atomthreads.lkf @@ -26,19 +26,19 @@ crtsi0.sm8 # Object files list - section reserved for STVD # -build\atomkernel.o -build\atommutex.o -build\atomqueue.o -build\atomsem.o -build\atomtimer.o -build\stm8s_clk.o -build\stm8s_gpio.o -build\stm8s_tim1.o -build\stm8s_uart2.o -build\tests-main.o -build\atomport.o -build\uart.o -build\atomport-asm-cosmic.o +build-cosmic\atomkernel.o +build-cosmic\atommutex.o +build-cosmic\atomqueue.o +build-cosmic\atomsem.o +build-cosmic\atomtimer.o +build-cosmic\stm8s_clk.o +build-cosmic\stm8s_gpio.o +build-cosmic\stm8s_tim1.o +build-cosmic\stm8s_uart2.o +build-cosmic\tests-main.o +build-cosmic\atomport.o +build-cosmic\uart.o +build-cosmic\atomport-asm-cosmic.o # Caller passes in test application object name as param1 @1 # @@ -54,7 +54,7 @@ libm0.sm8 # Interrupt vectors file # +seg .const -b 0x8000 -k -build/stm8_interrupt_vector.o +build-cosmic\stm8_interrupt_vector.o # # Defines From be6e60bf2fc6632497cd895cd6d9f150b0b5af8f Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:52:11 +0100 Subject: [PATCH 07/76] Improve support for platforms without stddef.h. NULL definition should now be provided by architecture port file atomport.h, which in most cases can just include stddef.h. --- kernel/atomkernel.c | 1 - kernel/atomport-template.h | 6 ++++++ ports/avr/atomport.h | 2 ++ ports/stm8/atomport.h | 2 ++ ports/stm8/uart.c | 1 - tests/kern1.c | 1 - tests/mutex1.c | 1 - tests/mutex2.c | 1 - tests/mutex7.c | 1 - tests/queue1.c | 1 - tests/queue4.c | 1 - tests/sem1.c | 1 - tests/sem2.c | 3 +-- tests/timer1.c | 3 +-- tests/timer3.c | 3 +-- tests/timer5.c | 3 +-- 16 files changed, 14 insertions(+), 17 deletions(-) diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 97daac4..8f4af3e 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -144,7 +144,6 @@ */ -#include #include "atom.h" diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 07671ea..4f47cb4 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -34,6 +34,12 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/** + * Definition of NULL. + * If stddef.h is available on the platform it is simplest to include it + * from this header, otherwise define below. + */ +#define NULL ((void *)(0)) /** * Architecture-specific types. diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index ec1cc78..094e17e 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -37,6 +37,8 @@ /* Portable uint8_t and friends available from stdint.h on this platform */ #include +/* Definition of NULL is available from stddef.h on this platform */ +#include /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index 119c2b5..bcd36e1 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -39,6 +39,8 @@ #include #endif +/* Definition of NULL is available from stddef.h on this platform */ +#include /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 diff --git a/ports/stm8/uart.c b/ports/stm8/uart.c index 352ea13..90515ac 100644 --- a/ports/stm8/uart.c +++ b/ports/stm8/uart.c @@ -1,5 +1,4 @@ #include -#include #include "stm8s.h" diff --git a/tests/kern1.c b/tests/kern1.c index 1695039..90a3991 100644 --- a/tests/kern1.c +++ b/tests/kern1.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomtests.h" diff --git a/tests/mutex1.c b/tests/mutex1.c index e3bc16a..015e8e2 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -27,7 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex2.c b/tests/mutex2.c index 9725f44..5432ec3 100644 --- a/tests/mutex2.c +++ b/tests/mutex2.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex7.c b/tests/mutex7.c index 9189dee..7d25fae 100644 --- a/tests/mutex7.c +++ b/tests/mutex7.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/queue1.c b/tests/queue1.c index f3a8938..8b50f91 100644 --- a/tests/queue1.c +++ b/tests/queue1.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue4.c b/tests/queue4.c index 3420882..e5c5d94 100644 --- a/tests/queue4.c +++ b/tests/queue4.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/sem1.c b/tests/sem1.c index b7b6335..54b7ddc 100644 --- a/tests/sem1.c +++ b/tests/sem1.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtests.h" diff --git a/tests/sem2.c b/tests/sem2.c index b83f8cf..f025e50 100644 --- a/tests/sem2.c +++ b/tests/sem2.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtests.h" @@ -321,4 +320,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/timer1.c b/tests/timer1.c index 2e2d940..6cc57d9 100644 --- a/tests/timer1.c +++ b/tests/timer1.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -246,4 +245,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/timer3.c b/tests/timer3.c index 0ea7a50..be81c14 100644 --- a/tests/timer3.c +++ b/tests/timer3.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -240,4 +239,4 @@ static void testCallback (POINTER cb_data) */ } -} \ No newline at end of file +} diff --git a/tests/timer5.c b/tests/timer5.c index 02ca33c..080a5b8 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -28,7 +28,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtimer.h" @@ -138,4 +137,4 @@ static void testCallback (POINTER cb_data) { /* Callback was called */ callback_ran_flag = TRUE; -} \ No newline at end of file +} From 789975075efe705dfbb2d258ed83f977e393fc13 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:00:21 +0100 Subject: [PATCH 08/76] STM8: Remove deprecated stack reference. --- ports/stm8/tests-main.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index bf83ee6..460c4bc 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -95,10 +95,6 @@ */ -/* Linker-provided startup stack location (usually top of RAM) */ -extern int _stack; - - /* Local data */ /* Application threads' TCBs */ From a87d40688b05717baa4567aedf8b9446ee8a2027 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:49:44 +0100 Subject: [PATCH 09/76] Use new build-cosmic output directory for Cosmic build objects. --- ports/stm8/atomthreads.lkf | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/ports/stm8/atomthreads.lkf b/ports/stm8/atomthreads.lkf index 1c2ada1..44e02bb 100644 --- a/ports/stm8/atomthreads.lkf +++ b/ports/stm8/atomthreads.lkf @@ -26,19 +26,19 @@ crtsi0.sm8 # Object files list - section reserved for STVD # -build\atomkernel.o -build\atommutex.o -build\atomqueue.o -build\atomsem.o -build\atomtimer.o -build\stm8s_clk.o -build\stm8s_gpio.o -build\stm8s_tim1.o -build\stm8s_uart2.o -build\tests-main.o -build\atomport.o -build\uart.o -build\atomport-asm-cosmic.o +build-cosmic\atomkernel.o +build-cosmic\atommutex.o +build-cosmic\atomqueue.o +build-cosmic\atomsem.o +build-cosmic\atomtimer.o +build-cosmic\stm8s_clk.o +build-cosmic\stm8s_gpio.o +build-cosmic\stm8s_tim1.o +build-cosmic\stm8s_uart2.o +build-cosmic\tests-main.o +build-cosmic\atomport.o +build-cosmic\uart.o +build-cosmic\atomport-asm-cosmic.o # Caller passes in test application object name as param1 @1 # @@ -54,7 +54,7 @@ libm0.sm8 # Interrupt vectors file # +seg .const -b 0x8000 -k -build/stm8_interrupt_vector.o +build-cosmic\stm8_interrupt_vector.o # # Defines From 8bb70d8a905488a8d7212e82001c7daf404c0b5f Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:52:11 +0100 Subject: [PATCH 10/76] Improve support for platforms without stddef.h. NULL definition should now be provided by architecture port file atomport.h, which in most cases can just include stddef.h. --- kernel/atomkernel.c | 6 ------ kernel/atomport-template.h | 6 ++++++ ports/avr/atomport.h | 2 ++ ports/stm8/atomport.h | 2 ++ ports/stm8/uart.c | 1 - tests/kern1.c | 6 ------ tests/mutex1.c | 7 ------- tests/mutex2.c | 6 ------ tests/mutex7.c | 6 ------ tests/queue1.c | 6 ------ tests/queue4.c | 6 ------ tests/sem1.c | 6 ------ tests/sem2.c | 6 ------ tests/timer1.c | 6 ------ tests/timer3.c | 6 ------ tests/timer5.c | 6 ------ 16 files changed, 10 insertions(+), 74 deletions(-) diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 4b53af1..9c0e276 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -143,12 +143,6 @@ * */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 07671ea..4f47cb4 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -34,6 +34,12 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/** + * Definition of NULL. + * If stddef.h is available on the platform it is simplest to include it + * from this header, otherwise define below. + */ +#define NULL ((void *)(0)) /** * Architecture-specific types. diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index ec1cc78..094e17e 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -37,6 +37,8 @@ /* Portable uint8_t and friends available from stdint.h on this platform */ #include +/* Definition of NULL is available from stddef.h on this platform */ +#include /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index 119c2b5..bcd36e1 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -39,6 +39,8 @@ #include #endif +/* Definition of NULL is available from stddef.h on this platform */ +#include /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 diff --git a/ports/stm8/uart.c b/ports/stm8/uart.c index 352ea13..90515ac 100644 --- a/ports/stm8/uart.c +++ b/ports/stm8/uart.c @@ -1,5 +1,4 @@ #include -#include #include "stm8s.h" diff --git a/tests/kern1.c b/tests/kern1.c index c467298..90a3991 100644 --- a/tests/kern1.c +++ b/tests/kern1.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/mutex1.c b/tests/mutex1.c index a2b03e7..4a340d2 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex2.c b/tests/mutex2.c index 7e90d22..5432ec3 100644 --- a/tests/mutex2.c +++ b/tests/mutex2.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atommutex.h" diff --git a/tests/mutex7.c b/tests/mutex7.c index e9edcb6..7d25fae 100644 --- a/tests/mutex7.c +++ b/tests/mutex7.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue1.c b/tests/queue1.c index 50089c6..8b50f91 100644 --- a/tests/queue1.c +++ b/tests/queue1.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue4.c b/tests/queue4.c index 46703d4..e5c5d94 100644 --- a/tests/queue4.c +++ b/tests/queue4.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/sem1.c b/tests/sem1.c index 69623eb..54b7ddc 100644 --- a/tests/sem1.c +++ b/tests/sem1.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/sem2.c b/tests/sem2.c index d7f0e40..f025e50 100644 --- a/tests/sem2.c +++ b/tests/sem2.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/timer1.c b/tests/timer1.c index d1bbf39..6cc57d9 100644 --- a/tests/timer1.c +++ b/tests/timer1.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/timer3.c b/tests/timer3.c index e6f9104..be81c14 100644 --- a/tests/timer3.c +++ b/tests/timer3.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/timer5.c b/tests/timer5.c index acf56b1..080a5b8 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -27,12 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif #include "atom.h" #include "atomsem.h" From f7dde300d40d557f75b284944439968343458f14 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 11/76] Change related to upstream merge. * STAND_ALONE conditional compilation is removed. * Previous interim commits are squashed. * printk.h is included from atomport.h * atom-types.h and atommport-types.h have been removed. Signed-off-by: Himanshu Chauhan --- kernel/atommutex.c | 2 -- kernel/atomqueue.c | 2 -- kernel/atomsem.c | 4 --- kernel/atomtimer.c | 2 -- ports/mips/8250-serial.c | 11 ++------ ports/mips/atomport-interrupts.c | 2 +- ports/mips/atomport-timer.c | 2 +- ports/mips/atomport-types.h | 44 -------------------------------- ports/mips/atomport.h | 16 +++++++++++- ports/mips/io.c | 2 +- ports/mips/printk.c | 5 +--- ports/mips/printk.h | 5 ++-- ports/mips/string.c | 2 +- ports/mips/string.h | 2 +- ports/mips/system.h | 2 +- ports/mips/tests-main.c | 2 +- ports/mips/vsprintf.c | 4 +-- tests/mutex4.c | 7 ----- tests/mutex5.c | 7 ----- tests/mutex8.c | 7 ----- tests/mutex9.c | 7 ----- tests/queue10.c | 7 ----- tests/queue2.c | 7 ----- tests/queue3.c | 7 ----- tests/queue5.c | 7 ----- tests/queue6.c | 7 ----- tests/queue7.c | 7 ----- tests/queue8.c | 7 ----- tests/queue9.c | 7 ----- tests/sem3.c | 7 ----- tests/sem4.c | 7 ----- tests/sem5.c | 7 ----- tests/sem6.c | 7 ----- tests/sem7.c | 7 ----- tests/sem8.c | 7 ----- tests/sem9.c | 7 ----- tests/timer2.c | 7 ----- tests/timer4.c | 7 ----- tests/timer5.c | 1 - tests/timer6.c | 7 ----- tests/timer7.c | 7 ----- 41 files changed, 29 insertions(+), 242 deletions(-) delete mode 100644 ports/mips/atomport-types.h diff --git a/kernel/atommutex.c b/kernel/atommutex.c index fdb4fff..6663e6e 100755 --- a/kernel/atommutex.c +++ b/kernel/atommutex.c @@ -102,8 +102,6 @@ #ifndef STAND_ALONE #include -#else -#include #endif #include "atom.h" diff --git a/kernel/atomqueue.c b/kernel/atomqueue.c index 70a65aa..97880a3 100755 --- a/kernel/atomqueue.c +++ b/kernel/atomqueue.c @@ -92,8 +92,6 @@ #ifndef STAND_ALONE #include -#else -#include #endif #include diff --git a/kernel/atomsem.c b/kernel/atomsem.c index d78bccc..8cd0567 100755 --- a/kernel/atomsem.c +++ b/kernel/atomsem.c @@ -91,10 +91,6 @@ #include #endif -#ifdef STAND_ALONE -#include -#endif - #include "atom.h" #include "atomsem.h" #include "atomtimer.h" diff --git a/kernel/atomtimer.c b/kernel/atomtimer.c index 136bf59..cf3a4e7 100755 --- a/kernel/atomtimer.c +++ b/kernel/atomtimer.c @@ -68,8 +68,6 @@ #ifndef STAND_ALONE #include -#else -#include #endif #include "atom.h" diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c index b1b2227..8d155dd 100644 --- a/ports/mips/8250-serial.c +++ b/ports/mips/8250-serial.c @@ -30,14 +30,9 @@ */ #include -#include -#include +#include #include <8250-serial.h> -//#define PORT1 (void *)0x140003f8 -//#define PORT2 (void *)0x140002F8 -//#define PORT3 (void *)0x140003E8 -//#define PORT4 (void *)0x140002E8 #define PORT1 (void *)0xc00003f8 static inline unsigned int serial_in(int offset) @@ -50,14 +45,12 @@ static inline void serial_out(int offset, int value) iowriteb(PORT1 + offset, value); } -int putch(uint8_t c) +void putch(uint8_t c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; serial_out(UART_TX, c); - - return 1; } void init_console() diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c index 970181f..e0065da 100644 --- a/ports/mips/atomport-interrupts.c +++ b/ports/mips/atomport-interrupts.c @@ -28,7 +28,7 @@ */ #include -#include +#include #include void mips_setup_interrupts() diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c index 9ed1889..0da14aa 100644 --- a/ports/mips/atomport-timer.c +++ b/ports/mips/atomport-timer.c @@ -28,7 +28,7 @@ */ #include -#include +#include #include #include diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h deleted file mode 100644 index b5c10f9..0000000 --- a/ports/mips/atomport-types.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_TYPES_H -#define __ATOMPORT_TYPES_H - -typedef signed int int32_t; -typedef signed short int16_t; -typedef signed char int8_t; -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -typedef long long int64_t; -typedef unsigned long size_t; - -#define UINT32 uint32_t - -#endif /* __ATOMPORT_TYPES_H */ diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 0df03eb..679cc85 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -30,9 +30,21 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H -#include "atomport-types.h" #include "atomport-timer.h" +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; + +#define UINT32 uint32_t + +#define NULL ((void *)(0)) + /** * Architecture-specific types. * Most of these are available from stdint.h on this platform, which is @@ -40,6 +52,8 @@ */ #define POINTER void * +#include "printk.h" + /* Critical region protection */ #define CRITICAL_STORE unsigned int status_reg #define CRITICAL_START() \ diff --git a/ports/mips/io.c b/ports/mips/io.c index 0ce15c4..90b714c 100644 --- a/ports/mips/io.c +++ b/ports/mips/io.c @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include uint8_t ioreadb (void *addr) { diff --git a/ports/mips/printk.c b/ports/mips/printk.c index 1ef0f64..c3a38f3 100644 --- a/ports/mips/printk.c +++ b/ports/mips/printk.c @@ -29,14 +29,11 @@ */ #include -#include - +#include #include static int8_t buf[2048]; -extern void putch(uint8_t ch); - /* Uses the above routine to output a string... */ void puts(const uint8_t *text) { diff --git a/ports/mips/printk.h b/ports/mips/printk.h index eeee752..bd1b192 100644 --- a/ports/mips/printk.h +++ b/ports/mips/printk.h @@ -33,10 +33,9 @@ #ifndef _PRINTK_H #define _PRINTK_H -#include -#include +#include "atomport.h" -extern void putch (uint8_t *ch); +extern void putch (uint8_t ch); extern void puts (const uint8_t *text); extern void printk (const char*format, ...); diff --git a/ports/mips/string.c b/ports/mips/string.c index bd65a10..b99b529 100644 --- a/ports/mips/string.c +++ b/ports/mips/string.c @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include void *memcpy(void *dest, const void *src, size_t count) diff --git a/ports/mips/string.h b/ports/mips/string.h index ed5f98a..bbccc25 100644 --- a/ports/mips/string.h +++ b/ports/mips/string.h @@ -31,7 +31,7 @@ #ifndef __STRING_H #define __STRING_H -#include +#include void *memcpy(void *dest, const void *src, size_t count); void *memset(void *dest, int8_t val, size_t count); diff --git a/ports/mips/system.h b/ports/mips/system.h index c655830..b8c25ad 100644 --- a/ports/mips/system.h +++ b/ports/mips/system.h @@ -31,7 +31,7 @@ #ifndef _SYSTEM_H #define _SYSTEM_H -#include +#include #include extern const uint8_t *kernel_name; diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 0deb23d..6d7c176 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -29,10 +29,10 @@ #include "atom.h" #include "atomport-private.h" +#include "atomport.h" #include "atomtests.h" #include "atomtimer.h" #include "system.h" -#include "printk.h" #include "atomport-interrupts.h" /* Constants */ diff --git a/ports/mips/vsprintf.c b/ports/mips/vsprintf.c index a957676..c8819fd 100644 --- a/ports/mips/vsprintf.c +++ b/ports/mips/vsprintf.c @@ -1,12 +1,12 @@ /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ /* * Wirzenius wrote this portably, Torvalds fucked it up :-) - * and Himanshu Fucked it up further for Freax :)) + * and Himanshu Fucked it up further :)) */ #include #include -#include +#include /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') diff --git a/tests/mutex4.c b/tests/mutex4.c index 28553fd..cbfc7bf 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex5.c b/tests/mutex5.c index c8dff89..a455fce 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex8.c b/tests/mutex8.c index fc3e62a..6ea01f0 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex9.c b/tests/mutex9.c index 394e1a7..9e20b97 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/queue10.c b/tests/queue10.c index 7a8187c..0a0ff0e 100644 --- a/tests/queue10.c +++ b/tests/queue10.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue2.c b/tests/queue2.c index 0365882..e45a7db 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue3.c b/tests/queue3.c index d2ea0e1..932465a 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue5.c b/tests/queue5.c index e7832cb..6ba450c 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue6.c b/tests/queue6.c index c2d3473..b50bc63 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue7.c b/tests/queue7.c index ab77781..e6cca06 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue8.c b/tests/queue8.c index 78921f8..5cfef6d 100644 --- a/tests/queue8.c +++ b/tests/queue8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue9.c b/tests/queue9.c index 78f1132..8091bf4 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/sem3.c b/tests/sem3.c index 113166f..d3d83f7 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem4.c b/tests/sem4.c index 5fb0eb9..64ad00e 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem5.c b/tests/sem5.c index a7e4f6d..3b7daa7 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem6.c b/tests/sem6.c index 106bbfa..f579f8e 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem7.c b/tests/sem7.c index b4595cb..c574e7c 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem8.c b/tests/sem8.c index 75d4896..59ee7a7 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem9.c b/tests/sem9.c index 48f5249..30fc0a0 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomsem.h" #include "atomtests.h" diff --git a/tests/timer2.c b/tests/timer2.c index b645f0e..883066e 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer4.c b/tests/timer4.c index f2864c6..c5c98e6 100644 --- a/tests/timer4.c +++ b/tests/timer4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer5.c b/tests/timer5.c index 080a5b8..231882b 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -27,7 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ - #include "atom.h" #include "atomsem.h" #include "atomtimer.h" diff --git a/tests/timer6.c b/tests/timer6.c index bb50abf..23fa557 100644 --- a/tests/timer6.c +++ b/tests/timer6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer7.c b/tests/timer7.c index 2e10731..7da3b85 100644 --- a/tests/timer7.c +++ b/tests/timer7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" From fa125d0883e306188bbf7c1a8cee1f9fb61524dc Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 26 May 2011 06:21:13 +0530 Subject: [PATCH 12/76] Fixed build break in mutex6.c Build break was introduced as part of changes done for upstream. Signed-off-by: Himanshu Chauhan --- tests/mutex6.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/mutex6.c b/tests/mutex6.c index 79bcd50..114ca52 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -27,14 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - - #include "atom.h" #include "atomtests.h" #include "atommutex.h" From b8e805e91a09b2ae8ac3277f17d9ed4aa8bb9129 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 26 May 2011 20:52:47 +0530 Subject: [PATCH 13/76] Removing secondary thread. Calling test_start in main instead. Signed-off-by: Himanshu Chauhan --- ports/mips/tests-main.c | 51 +++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 6d7c176..6a9cabc 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -120,7 +120,6 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; -static ATOM_TCB secondary_tcb; /* Main thread's stack area */ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); @@ -128,11 +127,8 @@ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned ( /* Idle thread's stack area */ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); -static uint8_t secondary_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); - /* Forward declarations */ static void main_thread_func (uint32_t data); -static void secondary_thread_func (uint32_t data); /** * \b main @@ -183,26 +179,19 @@ int main ( void ) MAIN_STACK_SIZE_BYTES); if (status == ATOM_OK) { - status = atomThreadCreate(&secondary_tcb, TEST_THREAD_PRIO, - secondary_thread_func, 0, - &secondary_thread_stack[MAIN_STACK_SIZE_BYTES], - MAIN_STACK_SIZE_BYTES); + mips_cpu_timer_enable(); - if (status == ATOM_OK) { - mips_cpu_timer_enable(); - - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); } } @@ -228,15 +217,11 @@ static void main_thread_func (uint32_t data) { while (1) { /* Put a message out on the UART */ - printk("Main Thread\n"); - atomTimerDelay(SYSTEM_TICKS_PER_SEC); - } -} - -static void secondary_thread_func (uint32_t data) -{ - while (1) { - printk("Secondary Thread\n"); - atomTimerDelay (SYSTEM_TICKS_PER_SEC); + printk("Running Tests... "); + if (test_start() != 0) { + printk("FAILED!\n"); + } else { + printk("SUCCESS!\n"); + } } } From 00d4e3f2affb088a053a6b7c981b62b1e14131ee Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 26 May 2011 23:27:05 +0100 Subject: [PATCH 14/76] Remove unnecessary stdio.h dependencies --- kernel/atommutex.c | 1 - kernel/atomqueue.c | 1 - kernel/atomsem.c | 1 - kernel/atomtimer.c | 1 - 4 files changed, 4 deletions(-) diff --git a/kernel/atommutex.c b/kernel/atommutex.c index cbb6371..e3543f3 100755 --- a/kernel/atommutex.c +++ b/kernel/atommutex.c @@ -101,7 +101,6 @@ */ -#include #include "atom.h" #include "atommutex.h" #include "atomtimer.h" diff --git a/kernel/atomqueue.c b/kernel/atomqueue.c index 78599f5..8ab0965 100755 --- a/kernel/atomqueue.c +++ b/kernel/atomqueue.c @@ -91,7 +91,6 @@ */ -#include #include #include "atom.h" diff --git a/kernel/atomsem.c b/kernel/atomsem.c index 6c5d32d..db1c2be 100755 --- a/kernel/atomsem.c +++ b/kernel/atomsem.c @@ -88,7 +88,6 @@ */ -#include #include "atom.h" #include "atomsem.h" #include "atomtimer.h" diff --git a/kernel/atomtimer.c b/kernel/atomtimer.c index 5376fcb..3693295 100755 --- a/kernel/atomtimer.c +++ b/kernel/atomtimer.c @@ -67,7 +67,6 @@ */ -#include #include "atom.h" From af84aa984863ed05ec791fba8fa927da360cc5ea Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 16:41:18 +0100 Subject: [PATCH 15/76] Add support for architectures with stack alignment requirements in preparation for various 32 bit ports. NOTE: The atomThreadCreate() and atmoOSInit() APIs have changed to take stack_bottom rather than stack_top and to allow optional stack-checking on a per-thread basis. --- kernel/atom.h | 6 ++-- kernel/atomkernel.c | 71 ++++++++++++++++++++++++-------------- kernel/atomport-template.h | 3 ++ ports/avr/atomport.h | 2 ++ ports/avr/tests-main.c | 21 ++++++----- ports/stm8/atomport.h | 2 ++ ports/stm8/tests-main.c | 7 ++-- tests/kern1.c | 12 +++---- tests/kern3.c | 8 ++--- tests/kern4.c | 16 ++++----- tests/mutex1.c | 8 ++--- tests/mutex2.c | 4 +-- tests/mutex3.c | 18 +++++----- tests/mutex4.c | 18 +++++----- tests/mutex5.c | 6 ++-- tests/mutex6.c | 6 ++-- tests/mutex7.c | 4 +-- tests/mutex8.c | 12 +++---- tests/mutex9.c | 4 +-- tests/queue2.c | 8 ++--- tests/queue3.c | 8 ++--- tests/queue5.c | 16 ++++----- tests/queue6.c | 4 +-- tests/queue7.c | 12 +++---- tests/queue9.c | 16 ++++----- tests/sem1.c | 8 ++--- tests/sem3.c | 16 ++++----- tests/sem4.c | 16 ++++----- tests/sem5.c | 4 +-- tests/sem6.c | 4 +-- tests/sem7.c | 4 +-- tests/sem8.c | 12 +++---- tests/sem9.c | 12 +++---- tests/timer2.c | 12 +++---- 34 files changed, 203 insertions(+), 177 deletions(-) diff --git a/kernel/atom.h b/kernel/atom.h index 43c3734..d71acc6 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -62,7 +62,7 @@ typedef struct atom_tcb /* Details used if thread stack-checking is required */ #ifdef ATOM_STACK_CHECKING - POINTER stack_top; /* Pointer to top of stack allocation */ + POINTER stack_bottom; /* Pointer to bottom of stack allocation */ uint32_t stack_size; /* Size of stack allocation in bytes */ #endif @@ -98,7 +98,7 @@ extern uint8_t atomOSStarted; /* Function prototypes */ -extern uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t stack_size); +extern uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check); extern void atomOSStart (void); extern void atomSched (uint8_t timer_tick); @@ -113,7 +113,7 @@ extern ATOM_TCB *tcbDequeuePriority (ATOM_TCB **tcb_queue_ptr, uint8_t priority) extern ATOM_TCB *atomCurrentContext (void); -extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size); +extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 8f4af3e..7521c70 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -369,25 +369,31 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) * new thread may be scheduled in before the function returns. * * Optionally prefills the thread stack with a known value to enable stack - * usage checking (if the ATOM_STACK_CHECKING macro is defined). + * usage checking (if the ATOM_STACK_CHECKING macro is defined and + * stack_check parameter is set to TRUE). * * @param[in] tcb_ptr Pointer to the thread's TCB storage * @param[in] priority Priority of the thread (0 to 255) * @param[in] entry_point Thread entry point * @param[in] entry_param Parameter passed to thread entry point - * @param[in] stack_top Top of the stack area + * @param[in] stack_bottom Bottom of the stack area * @param[in] stack_size Size of the stack area in bytes + * @param[in] stack_check TRUE to enable stack checking for this thread * * @retval ATOM_OK Success * @retval ATOM_ERR_PARAM Bad parameters * @retval ATOM_ERR_QUEUE Error putting the thread on the ready queue */ -uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size) +uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check) { CRITICAL_STORE; uint8_t status; + uint8_t *stack_top; +#ifdef ATOM_STACK_CHECKING + int32_t count; +#endif - if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_top == NULL) + if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_bottom == NULL) || (stack_size == 0)) { /* Bad parameters */ @@ -411,6 +417,13 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin tcb_ptr->entry_point = entry_point; tcb_ptr->entry_param = entry_param; + /** + * Calculate a pointer to the topmost stack entry, suitably aligned + * for the architecture. This may discard the top few bytes if the + * stack size is not a multiple of the stack entry/alignment size. + */ + stack_top = (uint8_t *)stack_bottom + (stack_size & ~(STACK_ALIGN_SIZE - 1)) - STACK_ALIGN_SIZE; + /** * Additional processing only required if stack-checking is * enabled. Incurs a slight overhead on each thread creation @@ -418,25 +431,29 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin * compiled out if not desired. */ #ifdef ATOM_STACK_CHECKING - - /* Store the stack details for use by the stack-check function */ - tcb_ptr->stack_top = stack_top; - tcb_ptr->stack_size = stack_size; - - /** - * Prefill the stack with a known value. This is used later in - * calls to atomThreadStackCheck() to get an indication of how - * much stack has been used during runtime. - */ - while (stack_size > 0) + /* Set up stack-checking if enabled for this thread */ + if (stack_check) { - /* Initialise all stack bytes from bottom up to 0x5A */ - *((uint8_t *)stack_top - (stack_size - 1)) = STACK_CHECK_BYTE; - stack_size--; + /* Store the stack details for use by the stack-check function */ + tcb_ptr->stack_bottom = stack_bottom; + tcb_ptr->stack_size = stack_size; + + /** + * Prefill the stack with a known value. This is used later in + * calls to atomThreadStackCheck() to get an indication of how + * much stack has been used during runtime. + */ + count = (int32_t)stack_size; + while (count > 0) + { + /* Initialise all stack bytes from top down to 0x5A */ + *((uint8_t *)stack_bottom + (count - 1)) = STACK_CHECK_BYTE; + count--; + } } #else - /* Avoid compiler warnings due to unused stack_size variable */ - stack_size = stack_size; + /* Avoid compiler warning due to unused parameter */ + stack_check = stack_check; #endif /** @@ -528,10 +545,10 @@ uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t else { /** - * Starting at the far end, count the unmodified areas until a + * Starting at the bottom end, count the unmodified areas until a * modified byte is found. */ - stack_ptr = (uint8_t *)tcb_ptr->stack_top - (tcb_ptr->stack_size - 1); + stack_ptr = (uint8_t *)tcb_ptr->stack_bottom; for (i = 0; i < tcb_ptr->stack_size; i++) { /* Loop until a modified byte is found */ @@ -647,13 +664,14 @@ ATOM_TCB *atomCurrentContext (void) * operating system facilities are being initialised. They are normally * enabled by the archFirstThreadRestore() routine in the architecture port. * - * @param[in] idle_thread_stack_top Ptr to top of stack area for idle thread + * @param[in] idle_thread_stack_bottom Ptr to bottom of stack for idle thread * @param[in] idle_thread_stack_size Size of idle thread stack in bytes + * @param[in] idle_thread_stack_check TRUE if stack checking required on idle thread * * @retval ATOM_OK Success * @retval ATOM_ERROR Initialisation error */ -uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size) +uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check) { uint8_t status; @@ -667,8 +685,9 @@ uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size IDLE_THREAD_PRIORITY, atomIdleThread, 0, - idle_thread_stack_top, - idle_thread_stack_size); + idle_thread_stack_bottom, + idle_thread_stack_size, + idle_thread_stack_check); /* Return status */ return (status); diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 4f47cb4..68772e7 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -41,6 +41,9 @@ */ #define NULL ((void *)(0)) +/* Size of each stack entry / stack alignment size (e.g. 8 bits) */ +#define STACK_ALIGN_SIZE sizeof(unsigned char) + /** * Architecture-specific types. * Uses the stdint.h naming convention, so if stdint.h is available on the diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index 094e17e..ba4dead 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -43,6 +43,8 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/* Size of each stack entry / stack alignment size (8 bits on AVR) */ +#define STACK_ALIGN_SIZE sizeof(uint8_t) /** * Architecture-specific types. diff --git a/ports/avr/tests-main.c b/ports/avr/tests-main.c index 427cd93..9cb5596 100644 --- a/ports/avr/tests-main.c +++ b/ports/avr/tests-main.c @@ -71,7 +71,7 @@ * stack for application code local variables etc. * * With all OS tests implemented to date on the AVR, the Main thread - * stack has not exceeded 198 bytes. To allow all tests to run we set + * stack has not exceeded 201 bytes. To allow all tests to run we set * a minimum main thread stack size of 204 bytes. This may increase in * future as the codebase changes but for the time being is enough to * cope with all of the automated tests. @@ -167,17 +167,15 @@ int main ( void ) /** * Initialise the OS before creating our threads. * - * Note that we tell the OS that the idle stack is half its actual - * size. This prevents it prefilling the bottom half with known - * values for stack-checkig purposes, which we cannot allow because - * we are temporarily using it for our own stack. The remainder will - * still be available once the OS is started, this only prevents the - * OS from prefilling it. + * Note that we cannot enable stack-checking on the idle thread on + * this platform because we are already using part of the idle + * thread's stack now as our startup stack. Prefilling for stack + * checking would overwrite our current stack. * * If you are not reusing the idle thread's stack during startup then - * you should pass in the correct size here. + * you are free to enable stack-checking here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, FALSE); if (status == ATOM_OK) { /* Enable the system tick timer */ @@ -186,8 +184,9 @@ int main ( void ) /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], - MAIN_STACK_SIZE_BYTES); + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); if (status == ATOM_OK) { /** diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index bcd36e1..caf87de 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -45,6 +45,8 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/* Size of each stack entry / stack alignment size (8 bits on STM8) */ +#define STACK_ALIGN_SIZE sizeof(u8) /** * Architecture-specific types. diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index 460c4bc..21b6d4d 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -139,7 +139,7 @@ NO_REG_SAVE void main ( void ) */ /* Initialise the OS before creating our threads */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], IDLE_STACK_SIZE_BYTES); + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, TRUE); if (status == ATOM_OK) { /* Enable the system tick timer */ @@ -148,8 +148,9 @@ NO_REG_SAVE void main ( void ) /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], - MAIN_STACK_SIZE_BYTES); + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); if (status == ATOM_OK) { /** diff --git a/tests/kern1.c b/tests/kern1.c index 90a3991..0f09756 100644 --- a/tests/kern1.c +++ b/tests/kern1.c @@ -63,8 +63,8 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad TCB pointer */ if (atomThreadCreate (NULL, TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + &test_thread_stack[0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad TCB check\n")); failures++; @@ -72,8 +72,8 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad entry point */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, NULL, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + &test_thread_stack[0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad entry check\n")); failures++; @@ -81,7 +81,7 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad stack pointer */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0, - NULL, TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + NULL, TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad stack ptr check\n")); failures++; @@ -89,7 +89,7 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad stack size */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], 0) != ATOM_ERR_PARAM) + &test_thread_stack[0], 0, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad stack size check\n")); failures++; diff --git a/tests/kern3.c b/tests/kern3.c index 20304f8..a149d72 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -95,8 +95,8 @@ uint32_t test_start (void) /* Create low priority thread */ if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; @@ -104,8 +104,8 @@ uint32_t test_start (void) /* Create high priority thread */ else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; diff --git a/tests/kern4.c b/tests/kern4.c index 909232e..23ed33b 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -97,29 +97,29 @@ uint32_t test_start (void) * a spell in which this thread was run. */ if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; diff --git a/tests/mutex1.c b/tests/mutex1.c index 015e8e2..40f1a9d 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -137,8 +137,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -200,8 +200,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/mutex2.c b/tests/mutex2.c index 5432ec3..df31d0e 100644 --- a/tests/mutex2.c +++ b/tests/mutex2.c @@ -143,8 +143,8 @@ uint32_t test_start (void) /* Create a test thread, the sole purpose of which is to own mutex2 */ g_owned = 0; if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); diff --git a/tests/mutex3.c b/tests/mutex3.c index f604430..958a657 100644 --- a/tests/mutex3.c +++ b/tests/mutex3.c @@ -108,8 +108,8 @@ uint32_t test_start (void) { /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -121,8 +121,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -134,8 +134,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -147,8 +147,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -288,4 +288,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex4.c b/tests/mutex4.c index b478517..6bf1281 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -101,8 +101,8 @@ uint32_t test_start (void) /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -113,8 +113,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -125,8 +125,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -137,8 +137,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -293,4 +293,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex5.c b/tests/mutex5.c index 9aa18f2..dc31558 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -95,8 +95,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -299,4 +299,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex6.c b/tests/mutex6.c index ca2c2d6..6e2890e 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -100,8 +100,8 @@ uint32_t test_start (void) /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -290,4 +290,4 @@ static void test_thread_func (uint32_t param) { atomTimerDelay (SYSTEM_TICKS_PER_SEC); } -} \ No newline at end of file +} diff --git a/tests/mutex7.c b/tests/mutex7.c index 7d25fae..32c6452 100644 --- a/tests/mutex7.c +++ b/tests/mutex7.c @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex8.c b/tests/mutex8.c index 14febb9..4892bb0 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -94,8 +94,8 @@ uint32_t test_start (void) /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -104,8 +104,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -114,8 +114,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/mutex9.c b/tests/mutex9.c index e509762..a690836 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -88,8 +88,8 @@ uint32_t test_start (void) /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/queue2.c b/tests/queue2.c index 8528ade..3b5f9f5 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -90,8 +90,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -147,8 +147,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/queue3.c b/tests/queue3.c index 277a4e3..8b4427e 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -107,8 +107,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is full */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -178,8 +178,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is full */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/queue5.c b/tests/queue5.c index bf07960..b6b81ec 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -115,8 +115,8 @@ uint32_t test_start (void) /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -128,8 +128,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -141,8 +141,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -154,8 +154,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/queue6.c b/tests/queue6.c index 4de62f0..1849b3b 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -107,8 +107,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO + 1, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); diff --git a/tests/queue7.c b/tests/queue7.c index 5b249d8..83eefa7 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -94,8 +94,8 @@ uint32_t test_start (void) /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -104,8 +104,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -114,8 +114,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/queue9.c b/tests/queue9.c index 1bc1034..10e740b 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -103,8 +103,8 @@ uint32_t test_start (void) { /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -115,8 +115,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -127,8 +127,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -139,8 +139,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem1.c b/tests/sem1.c index 54b7ddc..6842cd2 100644 --- a/tests/sem1.c +++ b/tests/sem1.c @@ -133,8 +133,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -200,8 +200,8 @@ uint32_t test_start (void) failures++; } else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/sem3.c b/tests/sem3.c index 6648b39..19ece62 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -103,8 +103,8 @@ uint32_t test_start (void) { /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -116,8 +116,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -129,8 +129,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -142,8 +142,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem4.c b/tests/sem4.c index 419195c..128276f 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -97,8 +97,8 @@ uint32_t test_start (void) { /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -109,8 +109,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -121,8 +121,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -133,8 +133,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem5.c b/tests/sem5.c index dc87f9f..4603071 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -84,8 +84,8 @@ uint32_t test_start (void) { /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem6.c b/tests/sem6.c index 851f9b8..532ec29 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -94,8 +94,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem7.c b/tests/sem7.c index 62fa16f..3835103 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -100,8 +100,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem8.c b/tests/sem8.c index 432cf32..ec27ba3 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -110,8 +110,8 @@ uint32_t test_start (void) /* Create thread 1: Higher priority than main thread so should sleep */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO - 1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -120,8 +120,8 @@ uint32_t test_start (void) /* Create thread 2: Same priority as main thread so should not sleep */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -130,8 +130,8 @@ uint32_t test_start (void) /* Create thread 3: Same priority as main thread so should not sleep */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/sem9.c b/tests/sem9.c index d7a86d6..fe660ba 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -87,8 +87,8 @@ uint32_t test_start (void) { /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -97,8 +97,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -107,8 +107,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/timer2.c b/tests/timer2.c index a606830..b9cbc55 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -73,8 +73,8 @@ uint32_t test_start (void) /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread1\n")); @@ -83,8 +83,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread2\n")); @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread3\n")); From 02660d0c807ca893fb235f208505d2388a0f90a3 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:15:38 +0100 Subject: [PATCH 16/76] AVR flash-program now checks sizes against the architecture. --- ports/avr/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/avr/Makefile b/ports/avr/Makefile index c5f214b..7fdb5c4 100644 --- a/ports/avr/Makefile +++ b/ports/avr/Makefile @@ -112,7 +112,7 @@ clean: # Send to STK500 program : $(BUILD_DIR)/$(app).hex - $(SIZE) -C $(BUILD_DIR)/$(app).elf + $(SIZE) -C --mcu=$(PART) $(BUILD_DIR)/$(app).elf $(UISP) -dprog=stk500 -dserial=$(UISP_DEV) -dpart=$(PART) --erase --upload --verify if=$(BUILD_DIR)/$(app).hex doxygen: From c471814b3c61a8230f464880512f34150e7ba42c Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:16:48 +0100 Subject: [PATCH 17/76] Reduce BSS size in queue5 and queue9 module - brings the BSS on ATmega16 to just under 1KB, allowing those tests to be run on that target. --- tests/queue5.c | 2 +- tests/queue9.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/queue5.c b/tests/queue5.c index b6b81ec..4cf5dbd 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -34,7 +34,7 @@ /* Number of queue entries */ -#define QUEUE_ENTRIES 8 +#define QUEUE_ENTRIES 4 /* Number of test threads */ diff --git a/tests/queue9.c b/tests/queue9.c index 10e740b..d914ee9 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -39,7 +39,7 @@ /* Test queue size */ -#define QUEUE_ENTRIES 8 +#define QUEUE_ENTRIES 4 /* Number of test threads */ From a630a8945d14b6421fb8a98f0120dcb13328f8a3 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:35:56 +0100 Subject: [PATCH 18/76] Add comments to critical region regarding nesting requirement. --- kernel/atomport-template.h | 7 ++++++- ports/avr/atomport.h | 7 ++++++- ports/stm8/atomport.h | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 68772e7..9f17635 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -60,7 +60,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ #define CRITICAL_STORE uint8_t sreg #define CRITICAL_START() sreg = SREG; cli(); #define CRITICAL_END() SREG = sreg diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index ba4dead..875bd15 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -54,7 +54,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ #define CRITICAL_STORE uint8_t sreg #define CRITICAL_START() sreg = SREG; cli(); #define CRITICAL_END() SREG = sreg diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index caf87de..2063bfb 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -60,7 +60,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ /* COSMIC: Use inline assembler */ #if defined(__CSMC__) From 1780000e1042cb4dc23b6dcd32bbb412fc3135cc Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Wed, 18 May 2011 22:35:45 +0530 Subject: [PATCH 19/76] Initial port of MIPS architecture. Completely untested. Shouldn't be merged to master. Signed-off-by: Himanshu Chauhan --- ports/mips/Doxyfile | 1161 +++++++++++++++++++++++++++++++++ ports/mips/Makefile | 107 +++ ports/mips/atomport-asm.s | 97 +++ ports/mips/atomport-entry.s | 230 +++++++ ports/mips/atomport-private.h | 148 +++++ ports/mips/atomport-tests.h | 48 ++ ports/mips/atomport-types.h | 42 ++ ports/mips/atomport.c | 75 +++ ports/mips/atomport.h | 53 ++ ports/mips/tests-main.c | 297 +++++++++ 10 files changed, 2258 insertions(+) create mode 100644 ports/mips/Doxyfile create mode 100644 ports/mips/Makefile create mode 100644 ports/mips/atomport-asm.s create mode 100644 ports/mips/atomport-entry.s create mode 100644 ports/mips/atomport-private.h create mode 100644 ports/mips/atomport-tests.h create mode 100644 ports/mips/atomport-types.h create mode 100644 ports/mips/atomport.c create mode 100644 ports/mips/atomport.h create mode 100644 ports/mips/tests-main.c diff --git a/ports/mips/Doxyfile b/ports/mips/Doxyfile new file mode 100644 index 0000000..e6f6571 --- /dev/null +++ b/ports/mips/Doxyfile @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = atomthreads + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen-avr + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ports/mips/Makefile b/ports/mips/Makefile new file mode 100644 index 0000000..016c290 --- /dev/null +++ b/ports/mips/Makefile @@ -0,0 +1,107 @@ +############ +# Settings # +############ + +# Build all test applications: +# make +# +# Program a test application using UISP (appname => test app e.g. sems1): +# make program app=appname + +# Location of build tools and atomthreads sources +KERNEL_DIR=../../kernel +TESTS_DIR=../../tests +CC=mips-linux-gnu-gcc +OBJCOPY=mips-linux-gnu-objcopy + +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Directory for built objects +BUILD_DIR=build + +# Port/application object files +APP_OBJECTS = atomport.o test-main.o +APP_ASM_OBJECTS = atomport-asm.o atomport-entry.o + +# Kernel object files +KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o + +# Collection of built objects (excluding test applications) +ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) +BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) + +# Test object files (dealt with separately as only one per application build) +TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c))) + +# Target application filenames (.elf and .hex) for each test object +TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) +TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS)) + +# Search build/output directory for dependencies +vpath %.o ./$(BUILD_DIR) +vpath %.elf ./$(BUILD_DIR) +vpath %.hex ./$(BUILD_DIR) + +# GCC flags +CFLAGS=-g -Wall -Werror + +# Enable stack-checking (disable if not required) +ifeq ($(STACK_CHECK),true) +CFLAGS += -DATOM_STACK_CHECKING +endif + + +################# +# Build targets # +################# + +# All tests +all: $(BUILD_DIR) $(TEST_HEXS) Makefile + +# Make build/output directory +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +# Test HEX files (one application build for each test) +$(TEST_HEXS): %.hex: %.elf + @echo Building $@ + $(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + +# Test ELF files (one application build for each test) +$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS) + $(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map + +# Kernel objects builder +$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c + $(CC) -c $(CFLAGS) -I. $< -o $(BUILD_DIR)/$(notdir $@) + +# Test objects builder +$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c + $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application C objects builder +$(APP_OBJECTS): %.o: ./%.c + $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application asm objects builder +$(APP_ASM_OBJECTS): %.o: ./%.s + $(CC) -c $(CFLAGS) -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# .lst file builder +%.lst: %.c + $(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + +# Clean +clean: + rm -f *.o *.elf *.map *.hex *.bin *.lst + rm -rf doxygen-kernel + rm -rf doxygen-avr + rm -rf build + +doxygen: + doxygen $(KERNEL_DIR)/Doxyfile + doxygen ./Doxyfile diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s new file mode 100644 index 0000000..b9c9cd3 --- /dev/null +++ b/ports/mips/atomport-asm.s @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + +.section .text + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +.globl archContextSwitch +archContextSwitch: + lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + lw k1, 0(a1) + + sw s0, (s0_IDX * 4)(a0) + sw s1, (s1_IDX * 4)(a0) + sw s2, (s2_IDX * 4)(a0) + sw s3, (s3_IDX * 4)(a0) + sw s4, (s4_IDX * 4)(a0) + sw s5, (s5_IDX * 4)(a0) + sw s6, (s6_IDX * 4)(a0) + sw s7, (s7_IDX * 4)(a0) + sw s8, (s8_IDX * 4)(a0) + sw sp, (sp_IDX * 4)(a0) + sw gp, (gp_IDX * 4)(a0) + + lw s0, (s0_IDX * 4)(a1) + lw s1, (s1_IDX * 4)(a1) + lw s2, (s2_IDX * 4)(a1) + lw s3, (s3_IDX * 4)(a1) + lw s4, (s4_IDX * 4)(a1) + lw s5, (s5_IDX * 4)(a1) + lw s6, (s6_IDX * 4)(a1) + lw s7, (s7_IDX * 4)(a1) + lw s8, (s8_IDX * 4)(a1) + lw sp, (sp_IDX * 4)(a1) + lw gp, (gp_IDX * 4)(a1) + + j ra + nop + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +.globl archFirstThreadRestore +archFirstThreadRestore: + move k0, a0 /* save the copy of tcb pointer in k0 */ + lw k1, 0(k0) /* Assume that sp_save_ptr is always at base of ATOM_TCB */ + lw a0, (a0_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop + eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s new file mode 100644 index 0000000..c746923 --- /dev/null +++ b/ports/mips/atomport-entry.s @@ -0,0 +1,230 @@ +/** + * Copyright (c) 2010 Himanshu Chauhan. + * All rights reserved. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * @file start.S + * @version 0.1 + * @author Himanshu Chauhan (hschauhan@nulltrace.org) + * @brief 24Kc startup file. + */ + +#include "atomport-private.h" + +.extern _stack_start +.section .start.text,"ax",@progbits + +EXCEPTION_VECTOR(_tlbmiss, 0x00, _handle_tlbmiss) +EXCEPTION_VECTOR(_cache_error, 0x100, _handle_cache_error) +EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception) +/* FIXME: We don't need this when in EIC mode. */ +EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt) + +LEAF(_start) + mtc0 ZERO, CP0_CONTEXT + nop + nop + nop + + /* globally disable interrupts until we are prepared. */ + disable_global_interrupts + + /* clear CPU timer counters. We don't want surprises. */ + mtc0 ZERO, CP0_COMPARE + mtc0 ZERO, CP0_COUNT + + /* Read number of tlb entries from config register */ + bal num_tlb_entries + nop + + /* initialize tlb */ + bal tlb_init + move A0, V0 + + la SP, _stack_start /* setup the stack (bss segment) */ + la T0, cpu_init + j T0 /* Call the C- code now */ + nop + +1: b 1b /* we should not come here whatsoever */ +END(_start) + +/* + * Read config 1 register and return the number + * of TLB entries in this CPU. + */ +LEAF(num_tlb_entries) + mfc0 A1, CP0_CONFIG1 + nop + nop + nop + srl V0, A1, 25 + and V0, V0, 0x3F + jr RA + nop +END(num_tlb_entries) + +/** + * tlb_init + * Initialize the TLB to a power-up state, guaranteeing that all entries + * are unique and invalid. + * Arguments: + * a0 = Maximum TLB index (from MMUSize field of C0_Config1) + * Returns: + * No value + * Restrictions: + * This routine must be called in unmapped space + * Algorithm: + * va = kseg0_base; + * for (entry = max_TLB_index ; entry >= 0, entry--) { + * while (TLB_Probe_Hit(va)) { + * va += Page_Size; + * } + * TLB_Write(entry, va, 0, 0, 0); + * } + */ +LEAF(tlb_init) + /* Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values + * are zero, and the default page size is used. + */ + mtc0 ZERO, CP0_ENTRYLO0 + /* Clear out PFN and valid bits */ + mtc0 ZERO, CP0_ENTRYLO1 + mtc0 ZERO, CP0_PAGEMASK + /* Clear out mask register */ + /* Start with the base address of kseg0 for the VA part of the TLB */ + li T0, 0x80000000 + /* + * Write the VA candidate to EntryHi and probe the TLB to see if if is + * already there. If it is, a write to the TLB may cause a machine + * check, so just increment the VA candidate by one page and try again. + */ +10: + mtc0 T0, CP0_ENTRYHI + /* Write VA candidate */ + tlbp_write_hazard + /* Clear EntryHi hazard (ssnop/ehb in R1/2) */ + tlbp + /* Probe the TLB to check for a match */ + tlbp_read_hazard + /* Clear Index hazard (ssnop/ehb in R1/2) */ + mfc0 T1, CP0_INDEX + addiu T0, (1 << S_EntryHiVPN2) + /* Read back flag to check for match */ + bgez T1, 10b + nop + /* Add 1 to VPN index in va */ + /* + * A write of the VPN candidate will be unique, so write this entry + * into the next index, decrement the index, and continue until the + * index goes negative (thereby writing all TLB entries) + */ + mtc0 A0, CP0_INDEX + /* Use this as next TLB index */ + tlbw_write_hazard + /* Clear Index hazard (ssnop/ehb in R1/2) */ + tlbwi + /* Write the TLB entry */ + /* Branch if more TLB entries to do */ + addiu A0, A0, -1 + bne A0, ZERO, 10b + nop + + /* Decrement the TLB index */ + /* + * Clear Index and EntryHi simply to leave the state constant for all + * returns + */ + mtc0 ZERO, CP0_INDEX + mtc0 ZERO, CP0_ENTRYHI + jr RA + /* Return to caller */ + nop +END(tlb_init) + +.extern vmm_cpu_handle_pagefault + +LEAF(_handle_tlbmiss) + disable_global_interrupts + move K0, SP + SAVE_INT_CONTEXT(_int_stack) + move A0, SP + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +END(_handle_tlbmiss) + +.extern generic_int_handler +.extern _int_stack +.extern vmm_regs_dump +LEAF(_handle_interrupt) + disable_global_interrupts + SAVE_INT_CONTEXT(_int_stack) + move A0, SP + bal generic_int_handler + nop + RESTORE_INT_CONTEXT(SP) + enable_global_interrupts + eret +END(_handle_interrupt) + +LEAF(_handle_cache_error) + b _handle_cache_error + nop +END(_handle_cache_error) + +LEAF(_handle_general_exception) + //move K0, SP + //SAVE_INT_CONTEXT(_int_stack) + //bal vmm_regs_dump + //move A0, SP + + b _handle_general_exception + nop +END(_handle_general_exception) + +/** + * A0 -> Contains virtual address. + * A1 -> Contains physical address. + * A2 -> TLB index: If -1 select automatically. + */ +.globl create_tlb_entry +LEAF(create_tlb_entry) + mtc0 A2, CP0_INDEX /* load the tlb index to be programmed. */ + srl A0, A0, 12 /* get the VPN */ + sll A0, A0, 12 + nop + mtc0 A0, CP0_ENTRYHI /* load VPN in entry hi */ + addi T0, A1, 0x1000 /* next PFN for entry lo1 in T0 */ + srl A1, A1, 12 /* get the PFN */ + sll A1, A1, 6 /* get the PFN */ + srl T0, T0, 12 + sll T0, T0, 6 + ori A1, A1, 0x7 /* mark the page writable, global and valid */ + mtc0 A1, CP0_ENTRYLO0 + ori T0, T0, 0x7 /* mark the next physical page writable, global and valid */ + nop + nop + mtc0 T0, CP0_ENTRYLO1 + nop + nop + nop + tlbwi + ehb + j RA + nop +END(create_tlb_entry) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h new file mode 100644 index 0000000..6c5cb84 --- /dev/null +++ b/ports/mips/atomport-private.h @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_PRIVATE_H_ +#define __ATOMPORT_PRIVATE_H_ + +#define zero $0 +#define at $1 +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define t8 $24 +#define t9 $25 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define s8 $30 +#define fp $30 +#define ra $31 + +#define NUM_REGISTERS 32 +#define WORD_SIZE 4 + +#define v0_IDX 0 +#define v1_IDX 1 +#define a0_IDX 2 +#define a1_IDX 3 +#define a2_IDX 4 +#define a3_IDX 5 +#define t0_IDX 6 +#define t1_IDX 7 +#define t2_IDX 8 +#define t3_IDX 9 +#define t4_IDX 10 +#define t5_IDX 11 +#define t6_IDX 12 +#define t7_IDX 13 +#define s0_IDX 14 +#define s1_IDX 15 +#define s2_IDX 16 +#define s3_IDX 17 +#define s4_IDX 18 +#define s5_IDX 19 +#define s6_IDX 20 +#define s7_IDX 21 +#define t8_IDX 22 +#define t9_IDX 23 +#define sp_IDX 24 +#define gp_IDX 25 +#define s8_IDX 26 +#define ra_IDX 27 +#define k0_IDX 28 +#define k1_IDX 29 +#define at_IDX 30 +#define zero_IDX 31 + +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_HWRENA $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_INTCTL $12,1 +#define CP0_SRSCTL $12,2 +#define CP0_SRSMAP $12,3 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_EBASE $15,1 +#define CP0_CONFIG $16 +#define CP0_CONFIG1 $16,1 +#define CP0_CONFIG2 $16,2 +#define CP0_CONFIG3 $16,3 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFCTL $25,0 +#define CP0_PERFCNT $25,1 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_DATALO $28,1 +#define CP0_TAGHI $29 +#define CP0_DATAHI $29,1 +#define CP0_ERRORPC $30 + +#define SAVE_REG(addr, reg, val) \ + sw reg, (reg ## _IDX * WORD_SIZE)(addr) + +#define LOAD_REG(addr, reg, val) \ + lw reg, (reg ## _IDX * WORD_SIZE)(addr) + +#endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h new file mode 100644 index 0000000..5b5a6de --- /dev/null +++ b/ports/mips/atomport-tests.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H +#define __ATOM_PORT_TESTS_H + +/* Include Atomthreads kernel API */ +#include "atom.h" + +/* Logger macro for viewing test results */ +/* FIXME: Add uart out routine once uart is supported */ +#define ATOMLOG(x) +#define _STR(x) + +/* Default thread stack size (in bytes) */ +#define TEST_THREAD_STACK_SIZE 128 + +/* Uncomment to enable logging of stack usage to UART */ +/* #define TESTS_LOG_STACK_USAGE */ + +#endif /* __ATOM_PORT_TESTS_H */ + diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h new file mode 100644 index 0000000..97ba780 --- /dev/null +++ b/ports/mips/atomport-types.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_TYPES_H +#define __ATOMPORT_TYPES_H + +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; + +#define UINT32 uint32_t + +#endif /* __ATOMPORT_TYPES_H */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c new file mode 100644 index 0000000..4b77a20 --- /dev/null +++ b/ports/mips/atomport.c @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +/** + * This function initialises each thread's stack during creation, before the + * thread is first run. New threads are scheduled in using the same + * context-switch function used for threads which were previously scheduled + * out, therefore this function should set up a stack context which looks + * much like a thread which has been scheduled out and had its context saved. + * We fill part of the stack with those registers which are involved in the + * context switch, including appropriate stack or register contents to cause + * the thread to branch to its entry point function when it is scheduled in. + * + * Interrupts should also be enabled whenever a thread is restored, hence + * ports may wish to explicitly include the interrupt-enable register here + * which will be restored when the thread is scheduled in. Other methods + * can be used to enable interrupts, however, without explicitly storing + * it in the thread's context. + */ +void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, + void (*entry_point)(UINT32), + UINT32 entry_param) +{ + +#define STORE_VAL(base, reg, val) \ + *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val + + void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS)); + + tcb_ptr->sp_save_ptr = stack_start; + + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); +} + diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h new file mode 100644 index 0000000..9a20931 --- /dev/null +++ b/ports/mips/atomport.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H +#define __ATOM_PORT_H + +#include "atomport-types.h" + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +/** + * Architecture-specific types. + * Most of these are available from stdint.h on this platform, which is + * included above. + */ +#define POINTER void * + +/* Critical region protection */ +#define CRITICAL_STORE +#define CRITICAL_START() __asm__ __volatile__("di $0\n\t") +#define CRITICAL_END() __asm__ __volatile__("ei $0\n\t"); + +/* Uncomment to enable stack-checking */ +/* #define ATOM_STACK_CHECKING */ + +#endif /* __ATOM_PORT_H */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c new file mode 100644 index 0000000..0ab9a94 --- /dev/null +++ b/ports/mips/tests-main.c @@ -0,0 +1,297 @@ +/* + * Copyright (c) 2010, Kelvin Lawson. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atom.h" +#include "atomport-private.h" +#include "atomtests.h" +#include "atomtimer.h" + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + * + * In this case, the idle stack is allocated on the BSS via the + * idle_thread_stack[] byte array. + */ +#define IDLE_STACK_SIZE_BYTES 128 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop + * flashing a LED. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + * + * With all OS tests implemented to date on the AVR, the Main thread + * stack has not exceeded 198 bytes. To allow all tests to run we set + * a minimum main thread stack size of 204 bytes. This may increase in + * future as the codebase changes but for the time being is enough to + * cope with all of the automated tests. + */ +#define MAIN_STACK_SIZE_BYTES 204 + + +/* + * Startup code stack + * + * Some stack space is required at initial startup for running the main() + * routine. This stack space is only temporarily required at first bootup + * and is no longer required as soon as the OS is started. By default + * GCC sets this to the top of RAM (RAMEND) and it grows down from there. + * Because we only need this temporarily, though, it would be wasteful to + * set aside a region at the top of RAM which is not used during runtime. + * + * What we do here is to reuse part of the idle thread's stack during + * initial startup. As soon as we enter the main() routine we move the + * stack pointer to half-way down the idle thread's stack. This is used + * temporarily while calls are made to atomOSInit(), atomThreadCreate() + * and atomOSStart(). Once the OS is started this stack area is no + * longer required, and can be used for its original purpose (for the + * idle thread's stack). + * + * This does mean, however, that we cannot monitor the stack usage of the + * idle thread. Stack usage is monitored by prefilling the stack with a + * known value, and we are obliterating some of that prefilled area by + * using it as our startup stack, so we cannot use the stack-checking API + * to get a true picture of idle thread stack usage. If you wish to + * monitor idle thread stack usage for your applications then you are + * free to use a different region for the startup stack (e.g. set aside + * an area permanently, or place it somewhere you know you can reuse + * later in the application). For the time being, this method gives us a + * simple way of reducing the memory consumption without having to add + * any special AVR-specific considerations to the automated test + * applications. + * + * This optimisation was required to allow some of the larger automated + * test modules to run on devices with 1KB of RAM. You should avoid doing + * this if you can afford to set aside 64 bytes or so, or if you are + * writing your own applications in which you have further control over + * where data is located. + */ + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + +/* STDIO stream */ +static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); + + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + + +/** + * \b main + * + * Program entry point. + * + * Sets up the AVR hardware resources (system tick timer interrupt) necessary + * for the OS to be started. Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + /** + * Reuse part of the idle thread's stack for the stack required + * during this startup function. + */ + SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1]; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /** + * Initialise the OS before creating our threads. + * + * Note that we tell the OS that the idle stack is half its actual + * size. This prevents it prefilling the bottom half with known + * values for stack-checkig purposes, which we cannot allow because + * we are temporarily using it for our own stack. The remainder will + * still be available once the OS is started, this only prevents the + * OS from prefilling it. + * + * If you are not reusing the idle thread's stack during startup then + * you should pass in the correct size here. + */ + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + if (status == ATOM_OK) + { + /* Enable the system tick timer */ + avrInitSystemTickTimer(); + + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], + MAIN_STACK_SIZE_BYTES); + if (status == ATOM_OK) + { + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1) + ; + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + uint32_t test_status; + int sleep_ticks; + + /* Enable all LEDs (STK500-specific) */ + DDRB = 0xFF; + PORTB = 0xFF; + + /* Initialise UART (9600bps) */ + if (uart_init(9600) != 0) + { + /* Error initialising UART */ + } + + /** + * Redirect stdout via the UART. Note that the UART write routine + * is protected via a semaphore, so the OS must be started before + * use of the UART. + */ + stdout = &uart_stdout; + + /* Put a message out on the UART */ + printf_P(PSTR("Go\n")); + + /* Start test. All tests use the same start API. */ + test_status = test_start(); + + /* Check main thread stack usage (if enabled) */ +#ifdef ATOM_STACK_CHECKING + if (test_status == 0) + { + uint32_t used_bytes, free_bytes; + + /* Check idle thread stack usage */ + if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) + { + /* Check the thread did not use up to the end of stack */ + if (free_bytes == 0) + { + printf_P (PSTR("Main stack overflow\n")); + test_status++; + } + + /* Log the stack usage */ +#ifdef TESTS_LOG_STACK_USAGE + printf_P (PSTR("MainUse:%d\n"), used_bytes); +#endif + } + + } +#endif + + /* Log final status */ + if (test_status == 0) + { + printf_P (PSTR("Pass\n")); + } + else + { + printf_P (PSTR("Fail(%d)\n"), test_status); + } + + /* Flash LED once per second if passed, very quickly if failed */ + sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8); + + /* Test finished, flash slowly for pass, fast for fail */ + while (1) + { + /* Toggle a LED (STK500-specific) */ + PORTB ^= (1 << 7); + + /* Sleep then toggle LED again */ + atomTimerDelay(sleep_ticks); + } + +} From 4b3c5e4ae374ae72b281e4e4b2b3d47430d12e98 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 20/76] Compilable MIPS code. Signed-off-by: Himanshu Chauhan --- kernel/atom-types.h | 37 ++++ ports/mips/8250-serial.c | 80 +++++++ ports/mips/8250-serial.h | 346 +++++++++++++++++++++++++++++++ ports/mips/Makefile | 64 ++++-- ports/mips/atomport-asm-macros.h | 285 +++++++++++++++++++++++++ ports/mips/atomport-entry.s | 231 ++++++--------------- ports/mips/atomport-private.h | 6 - ports/mips/atomport-tests.h | 4 +- ports/mips/atomport-types.h | 2 + ports/mips/io.c | 44 ++++ ports/mips/linker.ld | 74 +++++++ ports/mips/printk.c | 61 ++++++ ports/mips/printk.h | 43 ++++ ports/mips/stdarg.h | 28 +++ ports/mips/string.c | 61 ++++++ ports/mips/string.h | 42 ++++ ports/mips/system.h | 52 +++++ ports/mips/tests-main.c | 90 +------- ports/mips/vsprintf.c | 244 ++++++++++++++++++++++ tests/kern2.c | 3 + tests/kern3.c | 3 + tests/kern4.c | 3 + tests/mutex1.c | 1 - tests/mutex3.c | 3 + tests/mutex4.c | 6 + tests/mutex5.c | 6 + tests/mutex6.c | 7 + tests/mutex8.c | 6 + tests/mutex9.c | 6 + tests/queue10.c | 6 + tests/queue2.c | 6 + tests/queue3.c | 6 + tests/queue5.c | 6 + tests/queue6.c | 6 + tests/queue7.c | 6 + tests/queue8.c | 6 + tests/queue9.c | 6 + tests/sem3.c | 6 + tests/sem4.c | 6 + tests/sem5.c | 6 + tests/sem6.c | 6 + tests/sem7.c | 6 + tests/sem8.c | 6 + tests/sem9.c | 6 + tests/timer2.c | 6 + tests/timer4.c | 8 +- tests/timer6.c | 8 +- tests/timer7.c | 6 + 48 files changed, 1683 insertions(+), 273 deletions(-) create mode 100755 kernel/atom-types.h create mode 100644 ports/mips/8250-serial.c create mode 100644 ports/mips/8250-serial.h create mode 100644 ports/mips/atomport-asm-macros.h create mode 100644 ports/mips/io.c create mode 100755 ports/mips/linker.ld create mode 100644 ports/mips/printk.c create mode 100644 ports/mips/printk.h create mode 100755 ports/mips/stdarg.h create mode 100644 ports/mips/string.c create mode 100644 ports/mips/string.h create mode 100644 ports/mips/system.h create mode 100644 ports/mips/vsprintf.c diff --git a/kernel/atom-types.h b/kernel/atom-types.h new file mode 100755 index 0000000..898e2ca --- /dev/null +++ b/kernel/atom-types.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_TYPES_H +#define __ATOM_TYPES_H + +#include + +#define NULL ((void *)(0)) + +#endif /* __ATOM_TYPES_H */ diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c new file mode 100644 index 0000000..a7a3f59 --- /dev/null +++ b/ports/mips/8250-serial.c @@ -0,0 +1,80 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include +#include +#include <8250-serial.h> + +#define PORT1 (void *)0x140003f8 +#define PORT2 (void *)0x140002F8 +#define PORT3 (void *)0x140003E8 +#define PORT4 (void *)0x140002E8 + +static inline unsigned int serial_in(int offset) +{ + return ioreadb(PORT1 + offset); +} + +static inline void serial_out(int offset, int value) +{ + iowriteb(PORT1 + offset, value); +} + +int putch(uint8_t c) +{ + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(UART_TX, c); + + return 1; +} + +void init_console() +{ + serial_out(1 , 0); /* Turn off interrupts */ + + /* Communication Settings */ + serial_out(3 , 0x80); /* SET DLAB ON */ + serial_out(0 , 0x01); /* Set Baud rate - Divisor Latch Low Byte */ + /* 0x03 = 38,400 BPS */ + /* Default 0x01 = 115,200 BPS */ + /* 0x02 = 57,600 BPS */ + /* 0x06 = 19,200 BPS */ + /* 0x0C = 9,600 BPS */ + /* 0x18 = 4,800 BPS */ + /* 0x30 = 2,400 BPS */ + serial_out(1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */ + serial_out(3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ + serial_out(2 , 0xC7); /* FIFO Control Register */ + serial_out(4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ +} diff --git a/ports/mips/8250-serial.h b/ports/mips/8250-serial.h new file mode 100644 index 0000000..c7907a1 --- /dev/null +++ b/ports/mips/8250-serial.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _8250_SERIAL_H +#define _8250_SERIAL_H + +/* + * DLAB=0 + */ +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ +/* + * Sleep mode for ST16650 and TI16750. For the ST16650, EFR[4]=1 + */ +#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */ +#define UART_IIR_MSI 0x00 /* Modem status interrupt */ +#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */ +#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ +#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ + +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ +/* + * Note: The FIFO trigger levels are chip specific: + * RX:76 = 00 01 10 11 TX:54 = 00 01 10 11 + * PC16550D: 1 4 8 14 xx xx xx xx + * TI16C550A: 1 4 8 14 xx xx xx xx + * TI16C550C: 1 4 8 14 xx xx xx xx + * ST16C550: 1 4 8 14 xx xx xx xx + * ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2 + * NS16C552: 1 4 8 14 xx xx xx xx + * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 + * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 + * TI16C752: 8 16 56 60 8 16 32 56 + */ +#define UART_FCR_R_TRIG_00 0x00 +#define UART_FCR_R_TRIG_01 0x40 +#define UART_FCR_R_TRIG_10 0x80 +#define UART_FCR_R_TRIG_11 0xc0 +#define UART_FCR_T_TRIG_00 0x00 +#define UART_FCR_T_TRIG_01 0x10 +#define UART_FCR_T_TRIG_10 0x20 +#define UART_FCR_T_TRIG_11 0x30 + +#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ +#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ +#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ +#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ +#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ +/* 16650 definitions */ +#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */ +#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */ +#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */ +#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */ +#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */ +#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ +#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ +#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ +#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750) */ + +#define UART_LCR 3 /* Out: Line Control Register */ +/* + * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting + * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. + */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_SBC 0x40 /* Set break control */ +#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ +#define UART_LCR_EPAR 0x10 /* Even parity select */ +#define UART_LCR_PARITY 0x08 /* Parity Enable */ +#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */ +#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ +#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ +#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ +#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */ +#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */ +#define UART_MCR_XONANY 0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */ +#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */ +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ +#define UART_MCR_OUT2 0x08 /* Out2 complement */ +#define UART_MCR_OUT1 0x04 /* Out1 complement */ +#define UART_MCR_RTS 0x02 /* RTS complement */ +#define UART_MCR_DTR 0x01 /* DTR complement */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_TEMT 0x40 /* Transmitter empty */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_FE 0x08 /* Frame error indicator */ +#define UART_LSR_PE 0x04 /* Parity error indicator */ +#define UART_LSR_OE 0x02 /* Overrun error indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ + +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ +#define UART_MSR_RI 0x40 /* Ring Indicator */ +#define UART_MSR_DSR 0x20 /* Data Set Ready */ +#define UART_MSR_CTS 0x10 /* Clear to Send */ +#define UART_MSR_DDCD 0x08 /* Delta DCD */ +#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ +#define UART_MSR_DDSR 0x02 /* Delta DSR */ +#define UART_MSR_DCTS 0x01 /* Delta CTS */ +#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ + +#define UART_SCR 7 /* I/O: Scratch Register */ + +/* + * DLAB=1 + */ +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ + +/* + * LCR=0xBF (or DLAB=1 for 16C660) + */ +#define UART_EFR 2 /* I/O: Extended Features Register */ +#define UART_EFR_CTS 0x80 /* CTS flow control */ +#define UART_EFR_RTS 0x40 /* RTS flow control */ +#define UART_EFR_SCD 0x20 /* Special character detect */ +#define UART_EFR_ECB 0x10 /* Enhanced control bit */ +/* + * the low four bits control software flow control + */ + +/* + * LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654 + */ +#define UART_XON1 4 /* I/O: Xon character 1 */ +#define UART_XON2 5 /* I/O: Xon character 2 */ +#define UART_XOFF1 6 /* I/O: Xoff character 1 */ +#define UART_XOFF2 7 /* I/O: Xoff character 2 */ + +/* + * EFR[4]=1 MCR[6]=1, TI16C752 + */ +#define UART_TI752_TCR 6 /* I/O: transmission control register */ +#define UART_TI752_TLR 7 /* I/O: trigger level register */ + +/* + * LCR=0xBF, XR16C85x + */ +#define UART_TRG 0 /* FCTR bit 7 selects Rx or Tx + * In: Fifo count + * Out: Fifo custom trigger levels */ +/* + * These are the definitions for the Programmable Trigger Register + */ +#define UART_TRG_1 0x01 +#define UART_TRG_4 0x04 +#define UART_TRG_8 0x08 +#define UART_TRG_16 0x10 +#define UART_TRG_32 0x20 +#define UART_TRG_64 0x40 +#define UART_TRG_96 0x60 +#define UART_TRG_120 0x78 +#define UART_TRG_128 0x80 + +#define UART_FCTR 1 /* Feature Control Register */ +#define UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */ +#define UART_FCTR_RTS_4DELAY 0x01 +#define UART_FCTR_RTS_6DELAY 0x02 +#define UART_FCTR_RTS_8DELAY 0x03 +#define UART_FCTR_IRDA 0x04 /* IrDa data encode select */ +#define UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */ +#define UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */ +#define UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */ +#define UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */ +#define UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */ +#define UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */ +#define UART_FCTR_RX 0x00 /* Programmable trigger mode select */ +#define UART_FCTR_TX 0x80 /* Programmable trigger mode select */ + +/* + * LCR=0xBF, FCTR[6]=1 + */ +#define UART_EMSR 7 /* Extended Mode Select Register */ +#define UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */ +#define UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */ + +/* + * The Intel XScale on-chip UARTs define these bits + */ +#define UART_IER_DMAE 0x80 /* DMA Requests Enable */ +#define UART_IER_UUE 0x40 /* UART Unit Enable */ +#define UART_IER_NRZE 0x20 /* NRZ coding Enable */ +#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */ + +#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ + +#define UART_FCR_PXAR1 0x00 /* receive FIFO threshold = 1 */ +#define UART_FCR_PXAR8 0x40 /* receive FIFO threshold = 8 */ +#define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ +#define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ + + + + +/* + * These register definitions are for the 16C950 + */ +#define UART_ASR 0x01 /* Additional Status Register */ +#define UART_RFL 0x03 /* Receiver FIFO level */ +#define UART_TFL 0x04 /* Transmitter FIFO level */ +#define UART_ICR 0x05 /* Index Control Register */ + +/* The 16950 ICR registers */ +#define UART_ACR 0x00 /* Additional Control Register */ +#define UART_CPR 0x01 /* Clock Prescalar Register */ +#define UART_TCR 0x02 /* Times Clock Register */ +#define UART_CKS 0x03 /* Clock Select Register */ +#define UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */ +#define UART_RTL 0x05 /* Receiver Interrupt Trigger Level */ +#define UART_FCL 0x06 /* Flow Control Level Lower */ +#define UART_FCH 0x07 /* Flow Control Level Higher */ +#define UART_ID1 0x08 /* ID #1 */ +#define UART_ID2 0x09 /* ID #2 */ +#define UART_ID3 0x0A /* ID #3 */ +#define UART_REV 0x0B /* Revision */ +#define UART_CSR 0x0C /* Channel Software Reset */ +#define UART_NMR 0x0D /* Nine-bit Mode Register */ +#define UART_CTR 0xFF + +/* + * The 16C950 Additional Control Register + */ +#define UART_ACR_RXDIS 0x01 /* Receiver disable */ +#define UART_ACR_TXDIS 0x02 /* Transmitter disable */ +#define UART_ACR_DSRFC 0x04 /* DSR Flow Control */ +#define UART_ACR_TLENB 0x20 /* 950 trigger levels enable */ +#define UART_ACR_ICRRD 0x40 /* ICR Read enable */ +#define UART_ACR_ASREN 0x80 /* Additional status enable */ + + + +/* + * These definitions are for the RSA-DV II/S card, from + * + * Kiyokazu SUTO + */ + +#define UART_RSA_BASE (-8) + +#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */ + +#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */ +#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */ +#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */ +#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */ + +#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */ + +#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */ +#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */ +#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */ + +#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */ + +#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */ +#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */ +#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */ +#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occurred (1) */ +#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occurred */ + +#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */ + +#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */ + +#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */ + +#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */ + +/* + * The RSA DSV/II board has two fixed clock frequencies. One is the + * standard rate, and the other is 8 times faster. + */ +#define SERIAL_RSA_BAUD_BASE (921600) +#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) + +/* + * Extra serial register definitions for the internal UARTs + * in TI OMAP processors. + */ +#define UART_OMAP_MDR1 0x08 /* Mode definition register */ +#define UART_OMAP_MDR2 0x09 /* Mode definition register 2 */ +#define UART_OMAP_SCR 0x10 /* Supplementary control register */ +#define UART_OMAP_SSR 0x11 /* Supplementary status register */ +#define UART_OMAP_EBLR 0x12 /* BOF length register */ +#define UART_OMAP_OSC_12M_SEL 0x13 /* OMAP1510 12MHz osc select */ +#define UART_OMAP_MVER 0x14 /* Module version register */ +#define UART_OMAP_SYSC 0x15 /* System configuration register */ +#define UART_OMAP_SYSS 0x16 /* System status register */ +#define UART_OMAP_WER 0x17 /* Wake-up enable register */ + +#endif /* _8250_SERIAL_H */ + diff --git a/ports/mips/Makefile b/ports/mips/Makefile index 016c290..dc90cdf 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -14,6 +14,24 @@ TESTS_DIR=../../tests CC=mips-linux-gnu-gcc OBJCOPY=mips-linux-gnu-objcopy +# Check if verbosity is ON for build process +VERBOSE_DEFAULT := 0 +CMD_PREFIX_DEFAULT := @ +ifdef VERBOSE + ifeq ("$(origin VERBOSE)", "command line") + VB := $(VERBOSE) + else + VB := $(VERBOSE_DEFAULT) + endif +else + VB := $(VERBOSE_DEFAULT) +endif +ifeq ($(VB), 1) + V := +else + V := $(CMD_PREFIX_DEFAULT) +endif + # Enable stack-checking. WARNING: the full automated test suite currently # requires a little over 1KB RAM with stack-checking enabled. If you are # using a device with 1KB internal SRAM and no external SRAM then you @@ -24,14 +42,15 @@ OBJCOPY=mips-linux-gnu-objcopy BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o test-main.o -APP_ASM_OBJECTS = atomport-asm.o atomport-entry.o +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o + +APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o # Kernel object files KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o # Collection of built objects (excluding test applications) -ALL_OBJECTS = $(APP_OBJECTS) $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) +ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) # Test object files (dealt with separately as only one per application build) @@ -47,14 +66,23 @@ vpath %.elf ./$(BUILD_DIR) vpath %.hex ./$(BUILD_DIR) # GCC flags -CFLAGS=-g -Wall -Werror +CFLAGS= -g \ + -Wall \ + -Werror \ + -O \ + -fstrength-reduce \ + -fomit-frame-pointer \ + -finline-functions \ + -nostdinc \ + -fno-builtin \ + -fno-stack-protector \ + -DSTAND_ALONE # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) CFLAGS += -DATOM_STACK_CHECKING endif - ################# # Build targets # ################# @@ -68,36 +96,42 @@ $(BUILD_DIR): # Test HEX files (one application build for each test) $(TEST_HEXS): %.hex: %.elf - @echo Building $@ - $(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + $(if $(V), @echo " (HEX) $(subst $(build_dir)/,,$@)") + $(V)$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ # Test ELF files (one application build for each test) -$(TEST_ELFS): %.elf: %.o $(KERNEL_OBJECTS) $(APP_OBJECTS) $(APP_ASM_OBJECTS) - $(CC) $(CFLAGS) $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl,-Map,$(BUILD_DIR)/$(basename $@).map +$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl -T linker.ld # Kernel objects builder $(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c - $(CC) -c $(CFLAGS) -I. $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Test objects builder $(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c - $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Application C objects builder $(APP_OBJECTS): %.o: ./%.c - $(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # Application asm objects builder $(APP_ASM_OBJECTS): %.o: ./%.s - $(CC) -c $(CFLAGS) -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) # .lst file builder %.lst: %.c - $(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ # Clean clean: - rm -f *.o *.elf *.map *.hex *.bin *.lst + $(V)rm -f *.o *.elf *.map *.hex *.bin *.lst rm -rf doxygen-kernel rm -rf doxygen-avr rm -rf build diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h new file mode 100644 index 0000000..c71f1e1 --- /dev/null +++ b/ports/mips/atomport-asm-macros.h @@ -0,0 +1,285 @@ +#ifndef __ATOMPORT_ASM_MACROS_H_ +#define __ATOMPORT_ASM_MACROS_H_ + +#include + +#ifdef __ASSEMBLY__ /* to be called only from assembly */ + +#define LEAF(fn) \ + .globl fn; \ + .ent fn; \ +fn: + +#define END(fn) \ + .size fn,.-fn; \ + .end fn + +#define tlbp_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbp_read_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbw_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define enable_global_interrupts ei $0 +#define disable_global_interrupts di $0 + +#define EXCEPTION_VECTOR(_name, _offset, _where)\ + . = _offset; \ + .set noreorder; \ +_name: \ + b _where; \ + nop; + +#define SAVE_REG(reg, treg) \ + sw reg, ((reg ## _IDX) * 4)(treg) + +#define LOAD_REG(reg, treg) \ + lw reg, ((reg ## _IDX) * 4)(treg) + +#define SAVE_INT_CONTEXT(_int_sp) \ + move k0, sp; \ + la sp, _int_sp; \ + addiu sp, sp, -((CPU_USER_REG_COUNT + 1)* 4); \ + mfc0 k1, CP0_EPC; \ + SAVE_REG(v0,sp); \ + SAVE_REG(v1,sp); \ + SAVE_REG(a0,sp); \ + SAVE_REG(a1,sp); \ + SAVE_REG(a2,sp); \ + SAVE_REG(a3,sp); \ + SAVE_REG(t0,sp); \ + SAVE_REG(t1,sp); \ + SAVE_REG(t2,sp); \ + SAVE_REG(t3,sp); \ + SAVE_REG(t4,sp); \ + SAVE_REG(t5,sp); \ + SAVE_REG(t6,sp); \ + SAVE_REG(t7,sp); \ + SAVE_REG(s0,sp); \ + SAVE_REG(s1,sp); \ + SAVE_REG(s2,sp); \ + SAVE_REG(s3,sp); \ + SAVE_REG(s4,sp); \ + SAVE_REG(s5,sp); \ + SAVE_REG(s6,sp); \ + SAVE_REG(s7,sp); \ + SAVE_REG(t8,sp); \ + SAVE_REG(t9,sp); \ + SAVE_REG(gp,sp); \ + SAVE_REG(s8,sp); \ + SAVE_REG(ra,sp); \ + sw k0, (sp_IDX * 4)(sp); \ + sw k1, (CPU_USER_REG_COUNT * 4)(sp); + +#define RESTORE_INT_CONTEXT(treg) \ + lw k1, (CPU_USER_REG_COUNT * 4)(treg); \ + mtc0 k1, CP0_EPC; \ + LOAD_REG(v0,treg); \ + LOAD_REG(v1,treg); \ + LOAD_REG(a0,treg); \ + LOAD_REG(a1,treg); \ + LOAD_REG(a2,treg); \ + LOAD_REG(a3,treg); \ + LOAD_REG(t0,treg); \ + LOAD_REG(t1,treg); \ + LOAD_REG(t2,treg); \ + LOAD_REG(t3,treg); \ + LOAD_REG(t4,treg); \ + LOAD_REG(t5,treg); \ + LOAD_REG(t6,treg); \ + LOAD_REG(t7,treg); \ + LOAD_REG(s0,treg); \ + LOAD_REG(s1,treg); \ + LOAD_REG(s2,treg); \ + LOAD_REG(s3,treg); \ + LOAD_REG(s4,treg); \ + LOAD_REG(s5,treg); \ + LOAD_REG(s6,treg); \ + LOAD_REG(s7,treg); \ + LOAD_REG(t8,treg); \ + LOAD_REG(t9,treg); \ + LOAD_REG(gp,treg); \ + LOAD_REG(ra,treg); \ + LOAD_REG(s8,treg); \ + lw sp, (sp_IDX * 4)(treg); + +#endif /* __ASSEMBLY__ */ + +#define num_to_string(s) to_string(s) +#define to_string(s) #s + +#define IASM_SAVE_REG(reg, here) \ + "sw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + +#define IASM_LOAD_REG(reg, here) \ + "lw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + + +/* + * Macros to be used with C code. + */ +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + (unsigned long) __read_32bit_c0_register(reg, sel) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + __write_32bit_c0_register(reg, sel, val); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20) +#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* MIPSR2 */ +#define read_c0_hwrena() __read_32bit_c0_register($7, 0) +#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_intctl() __read_32bit_c0_register($12, 1) +#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val) + +#define read_c0_srsctl() __read_32bit_c0_register($12, 2) +#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val) + +#define read_c0_srsmap() __read_32bit_c0_register($12, 3) +#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val) + +#define read_c0_ebase() __read_32bit_c0_register($15, 1) +#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) + +#endif /* __ATOMPORT_ASM_MACROS_H_ */ diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index c746923..508ea5d 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -1,28 +1,33 @@ -/** - * Copyright (c) 2010 Himanshu Chauhan. - * All rights reserved. +/* + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: * - * @file start.S - * @version 0.1 - * @author Himanshu Chauhan (hschauhan@nulltrace.org) - * @brief 24Kc startup file. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atomport-private.h" +#include "atomport-asm-macros.h" .extern _stack_start .section .start.text,"ax",@progbits @@ -34,7 +39,7 @@ EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception) EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt) LEAF(_start) - mtc0 ZERO, CP0_CONTEXT + mtc0 zero, CP0_CONTEXT nop nop nop @@ -43,143 +48,42 @@ LEAF(_start) disable_global_interrupts /* clear CPU timer counters. We don't want surprises. */ - mtc0 ZERO, CP0_COMPARE - mtc0 ZERO, CP0_COUNT + mtc0 zero, CP0_COMPARE + mtc0 zero, CP0_COUNT - /* Read number of tlb entries from config register */ - bal num_tlb_entries - nop - - /* initialize tlb */ - bal tlb_init - move A0, V0 - - la SP, _stack_start /* setup the stack (bss segment) */ - la T0, cpu_init - j T0 /* Call the C- code now */ + la sp, _stack_start /* setup the stack (bss segment) */ + la t0, main + j t0 /* Call the C- code now */ nop 1: b 1b /* we should not come here whatsoever */ END(_start) -/* - * Read config 1 register and return the number - * of TLB entries in this CPU. - */ -LEAF(num_tlb_entries) - mfc0 A1, CP0_CONFIG1 - nop - nop - nop - srl V0, A1, 25 - and V0, V0, 0x3F - jr RA - nop -END(num_tlb_entries) - -/** - * tlb_init - * Initialize the TLB to a power-up state, guaranteeing that all entries - * are unique and invalid. - * Arguments: - * a0 = Maximum TLB index (from MMUSize field of C0_Config1) - * Returns: - * No value - * Restrictions: - * This routine must be called in unmapped space - * Algorithm: - * va = kseg0_base; - * for (entry = max_TLB_index ; entry >= 0, entry--) { - * while (TLB_Probe_Hit(va)) { - * va += Page_Size; - * } - * TLB_Write(entry, va, 0, 0, 0); - * } - */ -LEAF(tlb_init) - /* Clear PageMask, EntryLo0 and EntryLo1 so that valid bits are off, PFN values - * are zero, and the default page size is used. - */ - mtc0 ZERO, CP0_ENTRYLO0 - /* Clear out PFN and valid bits */ - mtc0 ZERO, CP0_ENTRYLO1 - mtc0 ZERO, CP0_PAGEMASK - /* Clear out mask register */ - /* Start with the base address of kseg0 for the VA part of the TLB */ - li T0, 0x80000000 - /* - * Write the VA candidate to EntryHi and probe the TLB to see if if is - * already there. If it is, a write to the TLB may cause a machine - * check, so just increment the VA candidate by one page and try again. - */ -10: - mtc0 T0, CP0_ENTRYHI - /* Write VA candidate */ - tlbp_write_hazard - /* Clear EntryHi hazard (ssnop/ehb in R1/2) */ - tlbp - /* Probe the TLB to check for a match */ - tlbp_read_hazard - /* Clear Index hazard (ssnop/ehb in R1/2) */ - mfc0 T1, CP0_INDEX - addiu T0, (1 << S_EntryHiVPN2) - /* Read back flag to check for match */ - bgez T1, 10b - nop - /* Add 1 to VPN index in va */ - /* - * A write of the VPN candidate will be unique, so write this entry - * into the next index, decrement the index, and continue until the - * index goes negative (thereby writing all TLB entries) - */ - mtc0 A0, CP0_INDEX - /* Use this as next TLB index */ - tlbw_write_hazard - /* Clear Index hazard (ssnop/ehb in R1/2) */ - tlbwi - /* Write the TLB entry */ - /* Branch if more TLB entries to do */ - addiu A0, A0, -1 - bne A0, ZERO, 10b - nop - - /* Decrement the TLB index */ - /* - * Clear Index and EntryHi simply to leave the state constant for all - * returns - */ - mtc0 ZERO, CP0_INDEX - mtc0 ZERO, CP0_ENTRYHI - jr RA - /* Return to caller */ - nop -END(tlb_init) - .extern vmm_cpu_handle_pagefault LEAF(_handle_tlbmiss) - disable_global_interrupts - move K0, SP - SAVE_INT_CONTEXT(_int_stack) - move A0, SP - bal vmm_cpu_handle_pagefault - nop - enable_global_interrupts - eret + //disable_global_interrupts + //move k0, sp + //SAVE_INT_CONTEXT(_int_stack) + //move a0, sp + //bal vmm_cpu_handle_pagefault + //nop + //enable_global_interrupts + //eret END(_handle_tlbmiss) .extern generic_int_handler .extern _int_stack .extern vmm_regs_dump LEAF(_handle_interrupt) - disable_global_interrupts - SAVE_INT_CONTEXT(_int_stack) - move A0, SP - bal generic_int_handler - nop - RESTORE_INT_CONTEXT(SP) - enable_global_interrupts - eret + //disable_global_interrupts + //SAVE_INT_CONTEXT(_int_stack) + //move a0, sp + //bal generic_int_handler + //nop + //RESTORE_INT_CONTEXT(sp) + //enable_global_interrupts + //eret END(_handle_interrupt) LEAF(_handle_cache_error) @@ -188,43 +92,38 @@ LEAF(_handle_cache_error) END(_handle_cache_error) LEAF(_handle_general_exception) - //move K0, SP - //SAVE_INT_CONTEXT(_int_stack) - //bal vmm_regs_dump - //move A0, SP - b _handle_general_exception nop END(_handle_general_exception) /** - * A0 -> Contains virtual address. - * A1 -> Contains physical address. - * A2 -> TLB index: If -1 select automatically. + * a0 -> Contains virtual address. + * a1 -> Contains physical address. + * a2 -> TLB index: If -1 select automatically. */ .globl create_tlb_entry LEAF(create_tlb_entry) - mtc0 A2, CP0_INDEX /* load the tlb index to be programmed. */ - srl A0, A0, 12 /* get the VPN */ - sll A0, A0, 12 + mtc0 a2, CP0_INDEX /* load the tlb index to be programmed. */ + srl a0, a0, 12 /* get the VPN */ + sll a0, a0, 12 nop - mtc0 A0, CP0_ENTRYHI /* load VPN in entry hi */ - addi T0, A1, 0x1000 /* next PFN for entry lo1 in T0 */ - srl A1, A1, 12 /* get the PFN */ - sll A1, A1, 6 /* get the PFN */ - srl T0, T0, 12 - sll T0, T0, 6 - ori A1, A1, 0x7 /* mark the page writable, global and valid */ - mtc0 A1, CP0_ENTRYLO0 - ori T0, T0, 0x7 /* mark the next physical page writable, global and valid */ + mtc0 a0, CP0_ENTRYHI /* load VPN in entry hi */ + addi t0, a1, 0x1000 /* next PFN for entry lo1 in T0 */ + srl a1, a1, 12 /* get the PFN */ + sll a1, a1, 6 /* get the PFN */ + srl t0, t0, 12 + sll t0, t0, 6 + ori a1, a1, 0x7 /* mark the page writable, global and valid */ + mtc0 a1, CP0_ENTRYLO0 + ori t0, t0, 0x7 /* mark the next physical page writable, global and valid */ nop nop - mtc0 T0, CP0_ENTRYLO1 + mtc0 t0, CP0_ENTRYLO1 nop nop nop tlbwi ehb - j RA + j ra nop END(create_tlb_entry) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h index 6c5cb84..e2af7e0 100644 --- a/ports/mips/atomport-private.h +++ b/ports/mips/atomport-private.h @@ -139,10 +139,4 @@ #define CP0_DATAHI $29,1 #define CP0_ERRORPC $30 -#define SAVE_REG(addr, reg, val) \ - sw reg, (reg ## _IDX * WORD_SIZE)(addr) - -#define LOAD_REG(addr, reg, val) \ - lw reg, (reg ## _IDX * WORD_SIZE)(addr) - #endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h index 5b5a6de..66b58eb 100644 --- a/ports/mips/atomport-tests.h +++ b/ports/mips/atomport-tests.h @@ -35,8 +35,8 @@ /* Logger macro for viewing test results */ /* FIXME: Add uart out routine once uart is supported */ -#define ATOMLOG(x) -#define _STR(x) +#define ATOMLOG printk +#define _STR /* Default thread stack size (in bytes) */ #define TEST_THREAD_STACK_SIZE 128 diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h index 97ba780..b5c10f9 100644 --- a/ports/mips/atomport-types.h +++ b/ports/mips/atomport-types.h @@ -36,6 +36,8 @@ typedef signed char int8_t; typedef unsigned int uint32_t; typedef unsigned short uint16_t; typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; #define UINT32 uint32_t diff --git a/ports/mips/io.c b/ports/mips/io.c new file mode 100644 index 0000000..0ce15c4 --- /dev/null +++ b/ports/mips/io.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 + +uint8_t ioreadb (void *addr) +{ + uint8_t rv; + rv = *((volatile uint8_t *)addr); + return rv; +} + +void iowriteb (void *addr, uint8_t data) +{ + *(volatile uint8_t *)addr = data; +} + diff --git a/ports/mips/linker.ld b/ports/mips/linker.ld new file mode 100755 index 0000000..98d6df6 --- /dev/null +++ b/ports/mips/linker.ld @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-tradbigmips") +OUTPUT_ARCH("mips") +ENTRY(_start) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.start.text) + *(.text) + . = ALIGN(4); + _etext = .; + } + + .data : + { + *(.data) + . = ALIGN(4); + _edata = .; + } + + .bss : + { + *(.bss) + . = ALIGN(4); + _ebss = .; + } + + .rodata : + { + *(.rodata .rodata.*) + . = ALIGN(4); + _erodata = .; + } + + PROVIDE(_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_stack_start = .); + PROVIDE(_int_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_int_stack = .); +} diff --git a/ports/mips/printk.c b/ports/mips/printk.c new file mode 100644 index 0000000..1ef0f64 --- /dev/null +++ b/ports/mips/printk.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +#include + +static int8_t buf[2048]; + +extern void putch(uint8_t ch); + +/* Uses the above routine to output a string... */ +void puts(const uint8_t *text) +{ + int32_t i; + + for (i = 0; i < strlen((const int8_t *)text); i++) { + putch(text[i]); + } +} + +void printk(const char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = vsprintf(buf, (const int8_t *)format, args); + va_end(args); + + puts((const uint8_t *)buf); +} + diff --git a/ports/mips/printk.h b/ports/mips/printk.h new file mode 100644 index 0000000..eeee752 --- /dev/null +++ b/ports/mips/printk.h @@ -0,0 +1,43 @@ +/* + * This file is part of Freax kernel. + * + * Copyright (c) Himanshu Chauhan 2009-10. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H +#define _PRINTK_H + +#include +#include + +extern void putch (uint8_t *ch); +extern void puts (const uint8_t *text); +extern void printk (const char*format, ...); + +#endif diff --git a/ports/mips/stdarg.h b/ports/mips/stdarg.h new file mode 100755 index 0000000..fd79ec0 --- /dev/null +++ b/ports/mips/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/ports/mips/string.c b/ports/mips/string.c new file mode 100644 index 0000000..bd65a10 --- /dev/null +++ b/ports/mips/string.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +void *memcpy(void *dest, const void *src, size_t count) +{ + const int8_t *sp = (const int8_t *)src; + int8_t *dp = (int8_t *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, int8_t val, size_t count) +{ + int8_t *temp = (int8_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) +{ + uint16_t *temp = (uint16_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +size_t strlen(const int8_t *str) +{ + size_t retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} diff --git a/ports/mips/string.h b/ports/mips/string.h new file mode 100644 index 0000000..ed5f98a --- /dev/null +++ b/ports/mips/string.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H +#define __STRING_H + +#include + +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *dest, int8_t val, size_t count); +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); +size_t strlen(const int8_t *str); + +#endif /* __STRING_H */ + diff --git a/ports/mips/system.h b/ports/mips/system.h new file mode 100644 index 0000000..c655830 --- /dev/null +++ b/ports/mips/system.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H +#define _SYSTEM_H + +#include +#include + +extern const uint8_t *kernel_name; +extern const uint8_t *kernel_version; +extern const uint8_t *kernel_bdate; +extern const uint8_t *kernel_btime; + +extern void *memcpy (void *dest, const void *src, size_t count); +extern void *memset (void *dest, int8_t val, size_t count); +extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); +extern size_t strlen (const int8_t *str); +extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); +extern void init_console (void); +extern int32_t arch_init (void); +extern uint8_t ioreadb (void *addr); +extern void iowriteb (void *addr, uint8_t data); + +#endif /* _SYSTEM_H */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 0ab9a94..af05049 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2010, Kelvin Lawson. All rights reserved. + * Copyright (c) 2011, Himanshu Chauhan. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,6 +31,8 @@ #include "atomport-private.h" #include "atomtests.h" #include "atomtimer.h" +#include "system.h" +#include "printk.h" /* Constants */ @@ -124,14 +126,9 @@ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; /* Idle thread's stack area */ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; -/* STDIO stream */ -static FILE uart_stdout = FDEV_SETUP_STREAM(uart_putchar, NULL, _FDEV_SETUP_WRITE); - - /* Forward declarations */ static void main_thread_func (uint32_t data); - /** * \b main * @@ -145,12 +142,6 @@ int main ( void ) { int8_t status; - /** - * Reuse part of the idle thread's stack for the stack required - * during this startup function. - */ - SP = (int)&idle_thread_stack[(IDLE_STACK_SIZE_BYTES/2) - 1]; - /** * Note: to protect OS structures and data during initialisation, * interrupts must remain disabled until the first thread @@ -172,11 +163,11 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], + (IDLE_STACK_SIZE_BYTES/2)); if (status == ATOM_OK) { - /* Enable the system tick timer */ - avrInitSystemTickTimer(); + /* FIXME: Enable the system tick timer */ /* Create an application thread */ status = atomThreadCreate(&main_tcb, @@ -221,77 +212,14 @@ int main ( void ) static void main_thread_func (uint32_t data) { uint32_t test_status; - int sleep_ticks; - /* Enable all LEDs (STK500-specific) */ - DDRB = 0xFF; - PORTB = 0xFF; - - /* Initialise UART (9600bps) */ - if (uart_init(9600) != 0) - { - /* Error initialising UART */ - } - - /** - * Redirect stdout via the UART. Note that the UART write routine - * is protected via a semaphore, so the OS must be started before - * use of the UART. - */ - stdout = &uart_stdout; + init_console(); /* Put a message out on the UART */ - printf_P(PSTR("Go\n")); + printk("Main Thread\n"); /* Start test. All tests use the same start API. */ test_status = test_start(); - /* Check main thread stack usage (if enabled) */ -#ifdef ATOM_STACK_CHECKING - if (test_status == 0) - { - uint32_t used_bytes, free_bytes; - - /* Check idle thread stack usage */ - if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) - { - /* Check the thread did not use up to the end of stack */ - if (free_bytes == 0) - { - printf_P (PSTR("Main stack overflow\n")); - test_status++; - } - - /* Log the stack usage */ -#ifdef TESTS_LOG_STACK_USAGE - printf_P (PSTR("MainUse:%d\n"), used_bytes); -#endif - } - - } -#endif - - /* Log final status */ - if (test_status == 0) - { - printf_P (PSTR("Pass\n")); - } - else - { - printf_P (PSTR("Fail(%d)\n"), test_status); - } - - /* Flash LED once per second if passed, very quickly if failed */ - sleep_ticks = (test_status == 0) ? SYSTEM_TICKS_PER_SEC : (SYSTEM_TICKS_PER_SEC/8); - - /* Test finished, flash slowly for pass, fast for fail */ - while (1) - { - /* Toggle a LED (STK500-specific) */ - PORTB ^= (1 << 7); - - /* Sleep then toggle LED again */ - atomTimerDelay(sleep_ticks); - } - + while(1); } diff --git a/ports/mips/vsprintf.c b/ports/mips/vsprintf.c new file mode 100644 index 0000000..a957676 --- /dev/null +++ b/ports/mips/vsprintf.c @@ -0,0 +1,244 @@ +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + * and Himanshu Fucked it up further for Freax :)) + */ + +#include +#include +#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const int8_t **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +/*#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; })*/ + +static uint32_t do_div (int32_t *n, int32_t base) +{ + uint32_t remainder = *n % base; + *n /= base; + return remainder; +} + +static int8_t * number(int8_t * str, int num, int32_t base, + int32_t size, int32_t precision, int32_t type) +{ + int8_t c,sign,tmp[36]; + const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int32_t i; + + if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; + if (type & LEFT) type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type & SIGN && num < 0) { + sign = '-'; + num = -num; + } else + sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); + if (sign) size--; + + if (type & SPECIAL) { + if (base == 16) { + size -= 2; + } else if (base == 8) { + size--; + } + } + + i = 0; + if (num == 0) + tmp[i++] = '0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while(size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) { + *str++ = '0'; + } else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while(size-- > 0) + *str++ = c; + while(i < precision--) + *str++ = '0'; + while(i-- > 0) + *str++ = tmp[i]; + while(size-- > 0) + *str++ = ' '; + return str; +} + +int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args) +{ + int32_t len; + int32_t i; + int8_t * str; + int8_t *s; + int32_t *ip; + + int32_t flags; /* flags to number() */ + + int32_t field_width; /* width of output field */ + int32_t precision; /* min. # of digits for integers; max + number of chars for from string */ + int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, int8_t *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int32_t *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} diff --git a/tests/kern2.c b/tests/kern2.c index 7387c89..d1d1254 100644 --- a/tests/kern2.c +++ b/tests/kern2.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /** * \b test_start diff --git a/tests/kern3.c b/tests/kern3.c index a149d72..4ff1caa 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/kern4.c b/tests/kern4.c index 23ed33b..2a06e95 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -31,6 +31,9 @@ #include "atom.h" #include "atomtests.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 diff --git a/tests/mutex1.c b/tests/mutex1.c index 40f1a9d..976a8ef 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -31,7 +31,6 @@ #include "atommutex.h" #include "atomtests.h" - /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/mutex3.c b/tests/mutex3.c index 958a657..b5e83a4 100644 --- a/tests/mutex3.c +++ b/tests/mutex3.c @@ -32,6 +32,9 @@ #include "atomtests.h" #include "atommutex.h" +#ifdef STAND_ALONE +#include +#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 diff --git a/tests/mutex4.c b/tests/mutex4.c index 6bf1281..f9b0dfd 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/mutex5.c b/tests/mutex5.c index dc31558..bddb800 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/mutex6.c b/tests/mutex6.c index 6e2890e..5d77512 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -27,6 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif + #include "atom.h" #include "atomtests.h" diff --git a/tests/mutex8.c b/tests/mutex8.c index 4892bb0..775174e 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atommutex.h" diff --git a/tests/mutex9.c b/tests/mutex9.c index a690836..01a9bda 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue10.c b/tests/queue10.c index ca6b6be..7a8187c 100644 --- a/tests/queue10.c +++ b/tests/queue10.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue2.c b/tests/queue2.c index 3b5f9f5..4138332 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue3.c b/tests/queue3.c index 8b4427e..f581bfb 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue5.c b/tests/queue5.c index 4cf5dbd..d30d6a2 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue6.c b/tests/queue6.c index 1849b3b..c897a81 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue7.c b/tests/queue7.c index 83eefa7..3f4f2ff 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomqueue.h" diff --git a/tests/queue8.c b/tests/queue8.c index 9064e47..78921f8 100644 --- a/tests/queue8.c +++ b/tests/queue8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/queue9.c b/tests/queue9.c index d914ee9..dde2d01 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem3.c b/tests/sem3.c index 19ece62..f32648a 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem4.c b/tests/sem4.c index 128276f..d919d4e 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem5.c b/tests/sem5.c index 4603071..9d0a551 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem6.c b/tests/sem6.c index 532ec29..8282f26 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem7.c b/tests/sem7.c index 3835103..3264393 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem8.c b/tests/sem8.c index ec27ba3..8380b8b 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" diff --git a/tests/sem9.c b/tests/sem9.c index fe660ba..f3f0e6a 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomsem.h" diff --git a/tests/timer2.c b/tests/timer2.c index b9cbc55..6c99947 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" diff --git a/tests/timer4.c b/tests/timer4.c index 1e74e88..f2864c6 100644 --- a/tests/timer4.c +++ b/tests/timer4.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" @@ -190,4 +196,4 @@ static void testCallback (POINTER cb_data) /* Not called at expected time, don't clear the location */ } -} \ No newline at end of file +} diff --git a/tests/timer6.c b/tests/timer6.c index da7f0da..bb50abf 100644 --- a/tests/timer6.c +++ b/tests/timer6.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtimer.h" @@ -152,4 +158,4 @@ static void testCallback (POINTER cb_data) { /* Callback was called */ *(int *)cb_data = TRUE; -} \ No newline at end of file +} diff --git a/tests/timer7.c b/tests/timer7.c index d2a7e54..2e10731 100644 --- a/tests/timer7.c +++ b/tests/timer7.c @@ -27,6 +27,12 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#ifndef STAND_ALONE +#include +#else +#include +#include +#endif #include "atom.h" #include "atomtests.h" From 83841d2673715bfc6c35af26f44449bcadc01128 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Fri, 20 May 2011 09:22:05 +0530 Subject: [PATCH 21/76] Half way debug code of context switching. Main thread comes up but the secondary threads doesn't get scheduled. Signed-off-by: Himanshu Chauhan --- kernel/atom.h | 2 +- kernel/atomkernel.c | 2 +- ports/mips/8250-serial.c | 9 ++-- ports/mips/Makefile | 2 +- ports/mips/atomport-asm.s | 63 +++++++++++++++---------- ports/mips/atomport-entry.s | 52 ++++++++++++-------- ports/mips/atomport-interrupts.c | 58 +++++++++++++++++++++++ ports/mips/atomport-interrupts.h | 38 +++++++++++++++ ports/mips/atomport-timer.c | 67 ++++++++++++++++++++++++++ ports/mips/atomport-timer.h | 37 +++++++++++++++ ports/mips/atomport.c | 27 ++++++----- ports/mips/atomport.h | 4 +- ports/mips/tests-main.c | 81 +++++++++++++++++++------------- 13 files changed, 341 insertions(+), 101 deletions(-) create mode 100644 ports/mips/atomport-interrupts.c create mode 100644 ports/mips/atomport-interrupts.h create mode 100644 ports/mips/atomport-timer.c create mode 100644 ports/mips/atomport-timer.h diff --git a/kernel/atom.h b/kernel/atom.h index d71acc6..b99512d 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -116,7 +116,7 @@ extern ATOM_TCB *atomCurrentContext (void); extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); -extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); +extern ATOM_TCB *archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); extern void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param); extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 7521c70..91d0a58 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -343,7 +343,7 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) curr_tcb = new_tcb; /* Call the architecture-specific context switch */ - archContextSwitch (old_tcb, new_tcb); + old_tcb = archContextSwitch (old_tcb, new_tcb); } /** diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c index a7a3f59..b1b2227 100644 --- a/ports/mips/8250-serial.c +++ b/ports/mips/8250-serial.c @@ -34,10 +34,11 @@ #include #include <8250-serial.h> -#define PORT1 (void *)0x140003f8 -#define PORT2 (void *)0x140002F8 -#define PORT3 (void *)0x140003E8 -#define PORT4 (void *)0x140002E8 +//#define PORT1 (void *)0x140003f8 +//#define PORT2 (void *)0x140002F8 +//#define PORT3 (void *)0x140003E8 +//#define PORT4 (void *)0x140002E8 +#define PORT1 (void *)0xc00003f8 static inline unsigned int serial_in(int offset) { diff --git a/ports/mips/Makefile b/ports/mips/Makefile index dc90cdf..aae07df 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -42,7 +42,7 @@ endif BUILD_DIR=build # Port/application object files -APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o atomport-interrupts.o atomport-timer.o APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index b9c9cd3..ce6adf9 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -27,7 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include +#include .section .text @@ -40,34 +40,44 @@ */ .globl archContextSwitch archContextSwitch: + move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + sw s0, (s0_IDX * 4)(k0) + sw s1, (s1_IDX * 4)(k0) + sw s2, (s2_IDX * 4)(k0) + sw s3, (s3_IDX * 4)(k0) + sw s4, (s4_IDX * 4)(k0) + sw s5, (s5_IDX * 4)(k0) + sw s6, (s6_IDX * 4)(k0) + sw s7, (s7_IDX * 4)(k0) + sw s8, (s8_IDX * 4)(k0) + sw sp, (sp_IDX * 4)(k0) + sw gp, (gp_IDX * 4)(k0) + mfc0 k1, CP0_EPC + nop + nop + nop + sw k1, (ra_IDX * 4)(k0) + lw k1, 0(a1) + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop - sw s0, (s0_IDX * 4)(a0) - sw s1, (s1_IDX * 4)(a0) - sw s2, (s2_IDX * 4)(a0) - sw s3, (s3_IDX * 4)(a0) - sw s4, (s4_IDX * 4)(a0) - sw s5, (s5_IDX * 4)(a0) - sw s6, (s6_IDX * 4)(a0) - sw s7, (s7_IDX * 4)(a0) - sw s8, (s8_IDX * 4)(a0) - sw sp, (sp_IDX * 4)(a0) - sw gp, (gp_IDX * 4)(a0) - - lw s0, (s0_IDX * 4)(a1) - lw s1, (s1_IDX * 4)(a1) - lw s2, (s2_IDX * 4)(a1) - lw s3, (s3_IDX * 4)(a1) - lw s4, (s4_IDX * 4)(a1) - lw s5, (s5_IDX * 4)(a1) - lw s6, (s6_IDX * 4)(a1) - lw s7, (s7_IDX * 4)(a1) - lw s8, (s8_IDX * 4)(a1) - lw sp, (sp_IDX * 4)(a1) - lw gp, (gp_IDX * 4)(a1) - - j ra + jr ra nop /** @@ -94,4 +104,5 @@ archFirstThreadRestore: nop nop nop + enable_global_interrupts eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index 508ea5d..d121f9b 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -51,6 +51,11 @@ LEAF(_start) mtc0 zero, CP0_COMPARE mtc0 zero, CP0_COUNT + li a0, 0xC0000000 /* FIXME: Remove these two hard codings */ + li a1, 0x14000000 + bal create_tlb_entry + move zero, a2 + la sp, _stack_start /* setup the stack (bss segment) */ la t0, main j t0 /* Call the C- code now */ @@ -59,31 +64,38 @@ LEAF(_start) 1: b 1b /* we should not come here whatsoever */ END(_start) -.extern vmm_cpu_handle_pagefault - LEAF(_handle_tlbmiss) - //disable_global_interrupts - //move k0, sp - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal vmm_cpu_handle_pagefault - //nop - //enable_global_interrupts - //eret +#if 0 + disable_global_interrupts + move k0, sp + SAVE_INT_CONTEXT(_int_stack) + move a0, sp + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +#else + b _handle_tlbmiss + nop +#endif END(_handle_tlbmiss) -.extern generic_int_handler +.extern handle_mips_systick .extern _int_stack -.extern vmm_regs_dump LEAF(_handle_interrupt) - //disable_global_interrupts - //SAVE_INT_CONTEXT(_int_stack) - //move a0, sp - //bal generic_int_handler - //nop - //RESTORE_INT_CONTEXT(sp) - //enable_global_interrupts - //eret + disable_global_interrupts + mfc0 k0, CP0_CAUSE + lui k1, 0x4000 + and k0, k1, k0 + beq k0, zero, 1f + nop + move k0, sp + la sp, _int_stack + bal handle_mips_systick + nop +1: + enable_global_interrupts + eret END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c new file mode 100644 index 0000000..970181f --- /dev/null +++ b/ports/mips/atomport-interrupts.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +void mips_setup_interrupts() +{ + uint32_t ebase = read_c0_ebase(); + ebase &= ~0x3FFF000UL; + write_c0_ebase(ebase); + + uint32_t sr = read_c0_status(); + sr &= ~(0x01UL << 22); + sr &= ~(0x3UL << 1); + write_c0_status(sr); + + uint32_t cause = read_c0_status(); + cause |= 0x01UL << 23; + write_c0_cause(cause); +} + +void mips_enable_global_interrupts(void) +{ + __asm__ __volatile__ ("ei $0\t\n"); +} + +void mips_disable_global_interrupts(void) +{ + __asm__ __volatile__("di $0\t\n"); +} diff --git a/ports/mips/atomport-interrupts.h b/ports/mips/atomport-interrupts.h new file mode 100644 index 0000000..41200de --- /dev/null +++ b/ports/mips/atomport-interrupts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_INTERRUPTS_H +#define __ATOMPORT_INTERRUPTS_H + +void mips_setup_interrupts(); +void mips_enable_global_interrupts(void); +void mips_disable_global_interrupts(void); +void handle_mips_systick(void); + +#endif /* __ATOMPORT_INTERRUPTS_H */ diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c new file mode 100644 index 0000000..9ed1889 --- /dev/null +++ b/ports/mips/atomport-timer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +/** CPU frequency in MHz */ +#define CPU_FREQ_MHZ 100 + +/** Number of counter counter should increase to get required ticks */ +#define COUNTER_TICK_COUNT ((1000000 * SYSTEM_TICKS_PER_SEC) / CPU_FREQ_MHZ) + +unsigned long long jiffies; + +void mips_cpu_timer_enable(void) +{ + uint32_t sr = read_c0_status(); + sr |= ((0x1UL << 7) << 8); + write_c0_status(sr); + + uint32_t cause = read_c0_cause(); + cause &= ~(0x1UL << 27); + write_c0_cause(cause); + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} + +void handle_mips_systick(void) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} diff --git a/ports/mips/atomport-timer.h b/ports/mips/atomport-timer.h new file mode 100644 index 0000000..b95dd7b --- /dev/null +++ b/ports/mips/atomport-timer.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TIMER_H +#define __ATOM_PORT_TIMER_H + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +void mips_cpu_timer_enable(void); + +#endif /* __ATOM_PORT_TIMER_H */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index 4b77a20..e3c7dcd 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -31,6 +31,7 @@ #include #include #include +#include /** * This function initialises each thread's stack during creation, before the @@ -56,20 +57,20 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - void *stack_start = (stack_top - (WORD_SIZE * NUM_REGISTERS)); + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_REGISTERS)); - tcb_ptr->sp_save_ptr = stack_start; + tcb_ptr->sp_save_ptr = (void *)stack_start; - STORE_VAL(stack_start, sp, stack_start); - STORE_VAL(stack_start, s8, stack_start); - STORE_VAL(stack_start, s1, 0); - STORE_VAL(stack_start, s2, 0); - STORE_VAL(stack_start, s3, 0); - STORE_VAL(stack_start, s4, 0); - STORE_VAL(stack_start, s5, 0); - STORE_VAL(stack_start, s6, 0); - STORE_VAL(stack_start, s7, 0); - STORE_VAL(stack_start, ra, entry_point); - STORE_VAL(stack_start, a0, entry_param); + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 9a20931..1f95356 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -31,9 +31,7 @@ #define __ATOM_PORT_H #include "atomport-types.h" - -/* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 100 +#include "atomport-timer.h" /** * Architecture-specific types. diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index af05049..0deb23d 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -33,6 +33,7 @@ #include "atomtimer.h" #include "system.h" #include "printk.h" +#include "atomport-interrupts.h" /* Constants */ @@ -47,7 +48,7 @@ * In this case, the idle stack is allocated on the BSS via the * idle_thread_stack[] byte array. */ -#define IDLE_STACK_SIZE_BYTES 128 +#define IDLE_STACK_SIZE_BYTES 4096 /* @@ -73,7 +74,7 @@ * future as the codebase changes but for the time being is enough to * cope with all of the automated tests. */ -#define MAIN_STACK_SIZE_BYTES 204 +#define MAIN_STACK_SIZE_BYTES 8192 /* @@ -119,15 +120,19 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; +static ATOM_TCB secondary_tcb; /* Main thread's stack area */ -static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Idle thread's stack area */ -static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); + +static uint8_t secondary_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); /* Forward declarations */ static void main_thread_func (uint32_t data); +static void secondary_thread_func (uint32_t data); /** * \b main @@ -163,35 +168,45 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], - (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES], + IDLE_STACK_SIZE_BYTES); if (status == ATOM_OK) { /* FIXME: Enable the system tick timer */ + mips_setup_interrupts(); + init_console(); /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], + &main_thread_stack[MAIN_STACK_SIZE_BYTES], MAIN_STACK_SIZE_BYTES); if (status == ATOM_OK) { - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + status = atomThreadCreate(&secondary_tcb, TEST_THREAD_PRIO, + secondary_thread_func, 0, + &secondary_thread_stack[MAIN_STACK_SIZE_BYTES], + MAIN_STACK_SIZE_BYTES); + + if (status == ATOM_OK) { + mips_cpu_timer_enable(); + + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } } - while (1) - ; + while (1); /* There was an error starting the OS if we reach here */ return (0); @@ -211,15 +226,17 @@ int main ( void ) */ static void main_thread_func (uint32_t data) { - uint32_t test_status; - - init_console(); - - /* Put a message out on the UART */ - printk("Main Thread\n"); - - /* Start test. All tests use the same start API. */ - test_status = test_start(); - - while(1); + while (1) { + /* Put a message out on the UART */ + printk("Main Thread\n"); + atomTimerDelay(SYSTEM_TICKS_PER_SEC); + } +} + +static void secondary_thread_func (uint32_t data) +{ + while (1) { + printk("Secondary Thread\n"); + atomTimerDelay (SYSTEM_TICKS_PER_SEC); + } } From 4e2b83c36f8471758230de2dd5478757f8688425 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Wed, 25 May 2011 22:31:13 +0530 Subject: [PATCH 22/76] Atomthreads working on MIPS (Qemu MIPS Machine). Signed-off-by: Himanshu Chauhan --- ports/mips/.gdbinit | 1 + ports/mips/atomport-asm-macros.h | 84 +++++++++--------- ports/mips/atomport-asm.s | 88 ++++++++++++++++--- ports/mips/atomport-entry.s | 22 ++++- ports/mips/atomport-private.h | 141 ++++++++++++++++--------------- ports/mips/atomport.c | 3 +- ports/mips/atomport.h | 19 ++++- 7 files changed, 230 insertions(+), 128 deletions(-) create mode 100644 ports/mips/.gdbinit diff --git a/ports/mips/.gdbinit b/ports/mips/.gdbinit new file mode 100644 index 0000000..24efe1e --- /dev/null +++ b/ports/mips/.gdbinit @@ -0,0 +1 @@ +target remote localhost:1234 diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h index c71f1e1..d73e9c7 100644 --- a/ports/mips/atomport-asm-macros.h +++ b/ports/mips/atomport-asm-macros.h @@ -63,17 +63,9 @@ _name: \ #define LOAD_REG(reg, treg) \ lw reg, ((reg ## _IDX) * 4)(treg) -#define SAVE_INT_CONTEXT(_int_sp) \ - move k0, sp; \ - la sp, _int_sp; \ - addiu sp, sp, -((CPU_USER_REG_COUNT + 1)* 4); \ +#define SAVE_INT_CONTEXT \ + addiu sp, sp, -((NUM_REGISTERS + 1)* 4); \ mfc0 k1, CP0_EPC; \ - SAVE_REG(v0,sp); \ - SAVE_REG(v1,sp); \ - SAVE_REG(a0,sp); \ - SAVE_REG(a1,sp); \ - SAVE_REG(a2,sp); \ - SAVE_REG(a3,sp); \ SAVE_REG(t0,sp); \ SAVE_REG(t1,sp); \ SAVE_REG(t2,sp); \ @@ -82,6 +74,14 @@ _name: \ SAVE_REG(t5,sp); \ SAVE_REG(t6,sp); \ SAVE_REG(t7,sp); \ + SAVE_REG(t8,sp); \ + SAVE_REG(t9,sp); \ + SAVE_REG(v0,sp); \ + SAVE_REG(v1,sp); \ + SAVE_REG(a0,sp); \ + SAVE_REG(a1,sp); \ + SAVE_REG(a2,sp); \ + SAVE_REG(a3,sp); \ SAVE_REG(s0,sp); \ SAVE_REG(s1,sp); \ SAVE_REG(s2,sp); \ @@ -90,45 +90,43 @@ _name: \ SAVE_REG(s5,sp); \ SAVE_REG(s6,sp); \ SAVE_REG(s7,sp); \ - SAVE_REG(t8,sp); \ - SAVE_REG(t9,sp); \ SAVE_REG(gp,sp); \ SAVE_REG(s8,sp); \ SAVE_REG(ra,sp); \ sw k0, (sp_IDX * 4)(sp); \ - sw k1, (CPU_USER_REG_COUNT * 4)(sp); + sw k1, (NUM_REGISTERS * 4)(sp); -#define RESTORE_INT_CONTEXT(treg) \ - lw k1, (CPU_USER_REG_COUNT * 4)(treg); \ +#define RESTORE_INT_CONTEXT \ + lw k1, (NUM_REGISTERS * 4)(sp); \ mtc0 k1, CP0_EPC; \ - LOAD_REG(v0,treg); \ - LOAD_REG(v1,treg); \ - LOAD_REG(a0,treg); \ - LOAD_REG(a1,treg); \ - LOAD_REG(a2,treg); \ - LOAD_REG(a3,treg); \ - LOAD_REG(t0,treg); \ - LOAD_REG(t1,treg); \ - LOAD_REG(t2,treg); \ - LOAD_REG(t3,treg); \ - LOAD_REG(t4,treg); \ - LOAD_REG(t5,treg); \ - LOAD_REG(t6,treg); \ - LOAD_REG(t7,treg); \ - LOAD_REG(s0,treg); \ - LOAD_REG(s1,treg); \ - LOAD_REG(s2,treg); \ - LOAD_REG(s3,treg); \ - LOAD_REG(s4,treg); \ - LOAD_REG(s5,treg); \ - LOAD_REG(s6,treg); \ - LOAD_REG(s7,treg); \ - LOAD_REG(t8,treg); \ - LOAD_REG(t9,treg); \ - LOAD_REG(gp,treg); \ - LOAD_REG(ra,treg); \ - LOAD_REG(s8,treg); \ - lw sp, (sp_IDX * 4)(treg); + LOAD_REG(s0,sp); \ + LOAD_REG(s1,sp); \ + LOAD_REG(s2,sp); \ + LOAD_REG(s3,sp); \ + LOAD_REG(s4,sp); \ + LOAD_REG(s5,sp); \ + LOAD_REG(s6,sp); \ + LOAD_REG(s7,sp); \ + LOAD_REG(v0,sp); \ + LOAD_REG(v1,sp); \ + LOAD_REG(a0,sp); \ + LOAD_REG(a1,sp); \ + LOAD_REG(a2,sp); \ + LOAD_REG(a3,sp); \ + LOAD_REG(t0,sp); \ + LOAD_REG(t1,sp); \ + LOAD_REG(t2,sp); \ + LOAD_REG(t3,sp); \ + LOAD_REG(t4,sp); \ + LOAD_REG(t5,sp); \ + LOAD_REG(t6,sp); \ + LOAD_REG(t7,sp); \ + LOAD_REG(t8,sp); \ + LOAD_REG(t9,sp); \ + LOAD_REG(gp,sp); \ + LOAD_REG(ra,sp); \ + LOAD_REG(s8,sp); \ + lw sp, (sp_IDX * 4)(sp); #endif /* __ASSEMBLY__ */ diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index ce6adf9..53cff5b 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -31,6 +31,7 @@ .section .text +.extern atomCurrentContext /** * Function that performs the contextSwitch. Whether its a voluntary release * of CPU by thread or a pre-emption, under both conditions this function is @@ -40,6 +41,18 @@ */ .globl archContextSwitch archContextSwitch: + /* + * Check if we are being called in interrupt + * context. If yes, we need to restore complete + * context and return directly from here. + */ + move k0, ra + bal atomCurrentContext + nop + beq v0, zero, __in_int_context + nop + + move ra, k0 move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ sw s0, (s0_IDX * 4)(k0) @@ -53,13 +66,22 @@ archContextSwitch: sw s8, (s8_IDX * 4)(k0) sw sp, (sp_IDX * 4)(k0) sw gp, (gp_IDX * 4)(k0) - mfc0 k1, CP0_EPC - nop - nop - nop - sw k1, (ra_IDX * 4)(k0) + sw ra, (ra_IDX * 4)(k0) + /* + * We are saving registers in non-interrupt context because + * a thread probably is trying to yield CPU. Storing zero + * in EPC offset differentiates this. When restoring the + * context, if EPC offset has zero we will restore only + * the partial context. Rest will be done by GCC while + * unwinding the call. + */ + sw zero, (cp0_epc_IDX * 4)(k0) lw k1, 0(a1) + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + lw s0, (s0_IDX * 4)(k1) lw s1, (s1_IDX * 4)(k1) lw s2, (s2_IDX * 4)(k1) @@ -71,15 +93,61 @@ archContextSwitch: lw s8, (s8_IDX * 4)(k1) lw sp, (sp_IDX * 4)(k1) lw gp, (gp_IDX * 4)(k1) - lw k0, (ra_IDX * 4)(k1) - mtc0 k0, CP0_EPC - nop - nop - nop + lw ra, (ra_IDX * 4)(k1) jr ra nop +__in_int_context: + move ra, k0 + /* + * In interrupt context, the interrupt handler + * saves the context for us. Its very well there + * and we don't need to do it again. + * + * We will figure out of the task that we are + * switching in was saved in interrupt context + * or otherwise. + */ + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + + /* + * Unwinding a task switched in non-interrupt context. + * So, restore only the partials. But since we are in + * interrupt mode, we will put ra in epc and do a eret + * so that we get out of interrupt mode and switch to + * the new task. + */ +__unwind_non_int_context: + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw ra, (ra_IDX * 4)(k1) + mtc0 ra, CP0_EPC + nop + nop + nop + j __ret_from_switch + nop + +__unwind_int_context: + move sp, k1 + RESTORE_INT_CONTEXT + +__ret_from_switch: + enable_global_interrupts + eret + /** * archFirstThreadRestore(ATOM_TCB *new_tcb) * diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index d121f9b..35b5735 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -89,13 +89,33 @@ LEAF(_handle_interrupt) and k0, k1, k0 beq k0, zero, 1f nop + + move k0, ra + move k1, v0 + bal atomCurrentContext + nop + beq v0, zero, 2f /* v0 should be current context */ + nop + + move ra, k0 + lw k0, 0(v0) + move v0, k1 + move k1, k0 + /* + * Note that we aren't loading any new SP. Context + * will be save on the interrupted threads' stack. + */ move k0, sp - la sp, _int_stack + move sp, k1 + SAVE_INT_CONTEXT bal handle_mips_systick nop + RESTORE_INT_CONTEXT 1: enable_global_interrupts eret + +2: b 2b END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h index e2af7e0..282dbb1 100644 --- a/ports/mips/atomport-private.h +++ b/ports/mips/atomport-private.h @@ -67,76 +67,77 @@ #define NUM_REGISTERS 32 #define WORD_SIZE 4 -#define v0_IDX 0 -#define v1_IDX 1 -#define a0_IDX 2 -#define a1_IDX 3 -#define a2_IDX 4 -#define a3_IDX 5 -#define t0_IDX 6 -#define t1_IDX 7 -#define t2_IDX 8 -#define t3_IDX 9 -#define t4_IDX 10 -#define t5_IDX 11 -#define t6_IDX 12 -#define t7_IDX 13 -#define s0_IDX 14 -#define s1_IDX 15 -#define s2_IDX 16 -#define s3_IDX 17 -#define s4_IDX 18 -#define s5_IDX 19 -#define s6_IDX 20 -#define s7_IDX 21 -#define t8_IDX 22 -#define t9_IDX 23 -#define sp_IDX 24 -#define gp_IDX 25 -#define s8_IDX 26 -#define ra_IDX 27 -#define k0_IDX 28 -#define k1_IDX 29 -#define at_IDX 30 -#define zero_IDX 31 +#define v0_IDX 0 +#define v1_IDX 1 +#define a0_IDX 2 +#define a1_IDX 3 +#define a2_IDX 4 +#define a3_IDX 5 +#define t0_IDX 6 +#define t1_IDX 7 +#define t2_IDX 8 +#define t3_IDX 9 +#define t4_IDX 10 +#define t5_IDX 11 +#define t6_IDX 12 +#define t7_IDX 13 +#define s0_IDX 14 +#define s1_IDX 15 +#define s2_IDX 16 +#define s3_IDX 17 +#define s4_IDX 18 +#define s5_IDX 19 +#define s6_IDX 20 +#define s7_IDX 21 +#define t8_IDX 22 +#define t9_IDX 23 +#define sp_IDX 24 +#define gp_IDX 25 +#define s8_IDX 26 +#define ra_IDX 27 +#define k0_IDX 28 +#define k1_IDX 29 +#define at_IDX 30 +#define zero_IDX 31 +#define cp0_epc_IDX 32 -#define CP0_INDEX $0 -#define CP0_RANDOM $1 -#define CP0_ENTRYLO0 $2 -#define CP0_ENTRYLO1 $3 -#define CP0_CONTEXT $4 -#define CP0_PAGEMASK $5 -#define CP0_WIRED $6 -#define CP0_HWRENA $7 -#define CP0_BADVADDR $8 -#define CP0_COUNT $9 -#define CP0_ENTRYHI $10 -#define CP0_COMPARE $11 -#define CP0_STATUS $12 -#define CP0_INTCTL $12,1 -#define CP0_SRSCTL $12,2 -#define CP0_SRSMAP $12,3 -#define CP0_CAUSE $13 -#define CP0_EPC $14 -#define CP0_PRID $15 -#define CP0_EBASE $15,1 -#define CP0_CONFIG $16 -#define CP0_CONFIG1 $16,1 -#define CP0_CONFIG2 $16,2 -#define CP0_CONFIG3 $16,3 -#define CP0_LLADDR $17 -#define CP0_WATCHLO $18 -#define CP0_WATCHHI $19 -#define CP0_DEBUG $23 -#define CP0_DEPC $24 -#define CP0_PERFCTL $25,0 -#define CP0_PERFCNT $25,1 -#define CP0_ECC $26 -#define CP0_CACHEERR $27 -#define CP0_TAGLO $28 -#define CP0_DATALO $28,1 -#define CP0_TAGHI $29 -#define CP0_DATAHI $29,1 -#define CP0_ERRORPC $30 +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_HWRENA $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_INTCTL $12,1 +#define CP0_SRSCTL $12,2 +#define CP0_SRSMAP $12,3 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_EBASE $15,1 +#define CP0_CONFIG $16 +#define CP0_CONFIG1 $16,1 +#define CP0_CONFIG2 $16,2 +#define CP0_CONFIG3 $16,3 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFCTL $25,0 +#define CP0_PERFCNT $25,1 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_DATALO $28,1 +#define CP0_TAGHI $29 +#define CP0_DATAHI $29,1 +#define CP0_ERRORPC $30 #endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index e3c7dcd..0509263 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -57,7 +57,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_REGISTERS)); + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * (NUM_REGISTERS + 1))); tcb_ptr->sp_save_ptr = (void *)stack_start; @@ -70,6 +70,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, STORE_VAL(stack_start, s5, 0); STORE_VAL(stack_start, s6, 0); STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, cp0_epc, entry_point); STORE_VAL(stack_start, ra, entry_point); STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 1f95356..0df03eb 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -41,9 +41,22 @@ #define POINTER void * /* Critical region protection */ -#define CRITICAL_STORE -#define CRITICAL_START() __asm__ __volatile__("di $0\n\t") -#define CRITICAL_END() __asm__ __volatile__("ei $0\n\t"); +#define CRITICAL_STORE unsigned int status_reg +#define CRITICAL_START() \ + __asm__ __volatile__("di %0\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ehb\t\n" \ + :"=r"(status_reg)); + +#define CRITICAL_END() \ + __asm__ __volatile__("ei %0\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ssnop\t\n" \ + "ehb\t\n" \ + ::"r"(status_reg)); /* Uncomment to enable stack-checking */ /* #define ATOM_STACK_CHECKING */ From 271eba687c459df3e366e8562a2f0ad832c579b7 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:52:11 +0100 Subject: [PATCH 23/76] Improve support for platforms without stddef.h. NULL definition should now be provided by architecture port file atomport.h, which in most cases can just include stddef.h. --- kernel/atomport-template.h | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 9f17635..ecb07ea 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -30,7 +30,6 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H - /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 From 05bd1987eabea7d785ca4561975542ae06076552 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 24/76] Change related to upstream merge. * STAND_ALONE conditional compilation is removed. * Previous interim commits are squashed. * printk.h is included from atomport.h * atom-types.h and atommport-types.h have been removed. Signed-off-by: Himanshu Chauhan --- ports/mips/8250-serial.c | 11 ++------ ports/mips/atomport-interrupts.c | 2 +- ports/mips/atomport-timer.c | 2 +- ports/mips/atomport-types.h | 44 -------------------------------- ports/mips/atomport.h | 16 +++++++++++- ports/mips/io.c | 2 +- ports/mips/printk.c | 5 +--- ports/mips/printk.h | 5 ++-- ports/mips/string.c | 2 +- ports/mips/string.h | 2 +- ports/mips/system.h | 2 +- ports/mips/tests-main.c | 2 +- ports/mips/vsprintf.c | 4 +-- tests/mutex4.c | 7 ----- tests/mutex5.c | 7 ----- tests/mutex8.c | 7 ----- tests/mutex9.c | 7 ----- tests/queue10.c | 7 ----- tests/queue2.c | 7 ----- tests/queue3.c | 7 ----- tests/queue5.c | 7 ----- tests/queue6.c | 7 ----- tests/queue7.c | 7 ----- tests/queue8.c | 7 ----- tests/queue9.c | 7 ----- tests/sem3.c | 7 ----- tests/sem4.c | 7 ----- tests/sem5.c | 7 ----- tests/sem6.c | 7 ----- tests/sem7.c | 7 ----- tests/sem8.c | 7 ----- tests/sem9.c | 7 ----- tests/timer2.c | 7 ----- tests/timer4.c | 7 ----- tests/timer5.c | 1 - tests/timer6.c | 7 ----- tests/timer7.c | 7 ----- 37 files changed, 29 insertions(+), 232 deletions(-) delete mode 100644 ports/mips/atomport-types.h diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c index b1b2227..8d155dd 100644 --- a/ports/mips/8250-serial.c +++ b/ports/mips/8250-serial.c @@ -30,14 +30,9 @@ */ #include -#include -#include +#include #include <8250-serial.h> -//#define PORT1 (void *)0x140003f8 -//#define PORT2 (void *)0x140002F8 -//#define PORT3 (void *)0x140003E8 -//#define PORT4 (void *)0x140002E8 #define PORT1 (void *)0xc00003f8 static inline unsigned int serial_in(int offset) @@ -50,14 +45,12 @@ static inline void serial_out(int offset, int value) iowriteb(PORT1 + offset, value); } -int putch(uint8_t c) +void putch(uint8_t c) { while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) ; serial_out(UART_TX, c); - - return 1; } void init_console() diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c index 970181f..e0065da 100644 --- a/ports/mips/atomport-interrupts.c +++ b/ports/mips/atomport-interrupts.c @@ -28,7 +28,7 @@ */ #include -#include +#include #include void mips_setup_interrupts() diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c index 9ed1889..0da14aa 100644 --- a/ports/mips/atomport-timer.c +++ b/ports/mips/atomport-timer.c @@ -28,7 +28,7 @@ */ #include -#include +#include #include #include diff --git a/ports/mips/atomport-types.h b/ports/mips/atomport-types.h deleted file mode 100644 index b5c10f9..0000000 --- a/ports/mips/atomport-types.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_TYPES_H -#define __ATOMPORT_TYPES_H - -typedef signed int int32_t; -typedef signed short int16_t; -typedef signed char int8_t; -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -typedef long long int64_t; -typedef unsigned long size_t; - -#define UINT32 uint32_t - -#endif /* __ATOMPORT_TYPES_H */ diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 0df03eb..679cc85 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -30,9 +30,21 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H -#include "atomport-types.h" #include "atomport-timer.h" +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; + +#define UINT32 uint32_t + +#define NULL ((void *)(0)) + /** * Architecture-specific types. * Most of these are available from stdint.h on this platform, which is @@ -40,6 +52,8 @@ */ #define POINTER void * +#include "printk.h" + /* Critical region protection */ #define CRITICAL_STORE unsigned int status_reg #define CRITICAL_START() \ diff --git a/ports/mips/io.c b/ports/mips/io.c index 0ce15c4..90b714c 100644 --- a/ports/mips/io.c +++ b/ports/mips/io.c @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include uint8_t ioreadb (void *addr) { diff --git a/ports/mips/printk.c b/ports/mips/printk.c index 1ef0f64..c3a38f3 100644 --- a/ports/mips/printk.c +++ b/ports/mips/printk.c @@ -29,14 +29,11 @@ */ #include -#include - +#include #include static int8_t buf[2048]; -extern void putch(uint8_t ch); - /* Uses the above routine to output a string... */ void puts(const uint8_t *text) { diff --git a/ports/mips/printk.h b/ports/mips/printk.h index eeee752..bd1b192 100644 --- a/ports/mips/printk.h +++ b/ports/mips/printk.h @@ -33,10 +33,9 @@ #ifndef _PRINTK_H #define _PRINTK_H -#include -#include +#include "atomport.h" -extern void putch (uint8_t *ch); +extern void putch (uint8_t ch); extern void puts (const uint8_t *text); extern void printk (const char*format, ...); diff --git a/ports/mips/string.c b/ports/mips/string.c index bd65a10..b99b529 100644 --- a/ports/mips/string.c +++ b/ports/mips/string.c @@ -28,7 +28,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include +#include #include void *memcpy(void *dest, const void *src, size_t count) diff --git a/ports/mips/string.h b/ports/mips/string.h index ed5f98a..bbccc25 100644 --- a/ports/mips/string.h +++ b/ports/mips/string.h @@ -31,7 +31,7 @@ #ifndef __STRING_H #define __STRING_H -#include +#include void *memcpy(void *dest, const void *src, size_t count); void *memset(void *dest, int8_t val, size_t count); diff --git a/ports/mips/system.h b/ports/mips/system.h index c655830..b8c25ad 100644 --- a/ports/mips/system.h +++ b/ports/mips/system.h @@ -31,7 +31,7 @@ #ifndef _SYSTEM_H #define _SYSTEM_H -#include +#include #include extern const uint8_t *kernel_name; diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 0deb23d..6d7c176 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -29,10 +29,10 @@ #include "atom.h" #include "atomport-private.h" +#include "atomport.h" #include "atomtests.h" #include "atomtimer.h" #include "system.h" -#include "printk.h" #include "atomport-interrupts.h" /* Constants */ diff --git a/ports/mips/vsprintf.c b/ports/mips/vsprintf.c index a957676..c8819fd 100644 --- a/ports/mips/vsprintf.c +++ b/ports/mips/vsprintf.c @@ -1,12 +1,12 @@ /* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ /* * Wirzenius wrote this portably, Torvalds fucked it up :-) - * and Himanshu Fucked it up further for Freax :)) + * and Himanshu Fucked it up further :)) */ #include #include -#include +#include /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') diff --git a/tests/mutex4.c b/tests/mutex4.c index f9b0dfd..5ecc316 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex5.c b/tests/mutex5.c index bddb800..5125d96 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex8.c b/tests/mutex8.c index 775174e..9b2af5c 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex9.c b/tests/mutex9.c index 01a9bda..36cf965 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/queue10.c b/tests/queue10.c index 7a8187c..0a0ff0e 100644 --- a/tests/queue10.c +++ b/tests/queue10.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue2.c b/tests/queue2.c index 4138332..e2ccff6 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue3.c b/tests/queue3.c index f581bfb..dd7eb1a 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue5.c b/tests/queue5.c index d30d6a2..a3c15d9 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue6.c b/tests/queue6.c index c897a81..68e43a2 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue7.c b/tests/queue7.c index 3f4f2ff..061bc20 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue8.c b/tests/queue8.c index 78921f8..5cfef6d 100644 --- a/tests/queue8.c +++ b/tests/queue8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue9.c b/tests/queue9.c index dde2d01..0907928 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/sem3.c b/tests/sem3.c index f32648a..33e06ad 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem4.c b/tests/sem4.c index d919d4e..193b1e2 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem5.c b/tests/sem5.c index 9d0a551..6a00750 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem6.c b/tests/sem6.c index 8282f26..7aebda1 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem7.c b/tests/sem7.c index 3264393..337a7b5 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem8.c b/tests/sem8.c index 8380b8b..5f2ecea 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem9.c b/tests/sem9.c index f3f0e6a..f2f6c55 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomsem.h" #include "atomtests.h" diff --git a/tests/timer2.c b/tests/timer2.c index 6c99947..e75defc 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer4.c b/tests/timer4.c index f2864c6..c5c98e6 100644 --- a/tests/timer4.c +++ b/tests/timer4.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer5.c b/tests/timer5.c index 080a5b8..231882b 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -27,7 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ - #include "atom.h" #include "atomsem.h" #include "atomtimer.h" diff --git a/tests/timer6.c b/tests/timer6.c index bb50abf..23fa557 100644 --- a/tests/timer6.c +++ b/tests/timer6.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer7.c b/tests/timer7.c index 2e10731..7da3b85 100644 --- a/tests/timer7.c +++ b/tests/timer7.c @@ -27,13 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - #include "atom.h" #include "atomtests.h" From 4ba6c9d9a7c53c25646f7f05dd4b7691a72816c5 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 26 May 2011 06:21:13 +0530 Subject: [PATCH 25/76] Fixed build break in mutex6.c Build break was introduced as part of changes done for upstream. Signed-off-by: Himanshu Chauhan --- tests/mutex6.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/tests/mutex6.c b/tests/mutex6.c index 5d77512..b47b7aa 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -27,14 +27,6 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef STAND_ALONE -#include -#else -#include -#include -#endif - - #include "atom.h" #include "atomtests.h" #include "atommutex.h" From dca450ffb85fcd5bc6c0be666d8867514275ee37 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 26 May 2011 20:52:47 +0530 Subject: [PATCH 26/76] Removing secondary thread. Calling test_start in main instead. Signed-off-by: Himanshu Chauhan --- ports/mips/tests-main.c | 51 +++++++++++++++-------------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 6d7c176..6a9cabc 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -120,7 +120,6 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; -static ATOM_TCB secondary_tcb; /* Main thread's stack area */ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); @@ -128,11 +127,8 @@ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned ( /* Idle thread's stack area */ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); -static uint8_t secondary_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); - /* Forward declarations */ static void main_thread_func (uint32_t data); -static void secondary_thread_func (uint32_t data); /** * \b main @@ -183,26 +179,19 @@ int main ( void ) MAIN_STACK_SIZE_BYTES); if (status == ATOM_OK) { - status = atomThreadCreate(&secondary_tcb, TEST_THREAD_PRIO, - secondary_thread_func, 0, - &secondary_thread_stack[MAIN_STACK_SIZE_BYTES], - MAIN_STACK_SIZE_BYTES); + mips_cpu_timer_enable(); - if (status == ATOM_OK) { - mips_cpu_timer_enable(); - - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); } } @@ -228,15 +217,11 @@ static void main_thread_func (uint32_t data) { while (1) { /* Put a message out on the UART */ - printk("Main Thread\n"); - atomTimerDelay(SYSTEM_TICKS_PER_SEC); - } -} - -static void secondary_thread_func (uint32_t data) -{ - while (1) { - printk("Secondary Thread\n"); - atomTimerDelay (SYSTEM_TICKS_PER_SEC); + printk("Running Tests... "); + if (test_start() != 0) { + printk("FAILED!\n"); + } else { + printk("SUCCESS!\n"); + } } } From 1e80052c98b9679a4b767d7aa9e7588fe5597111 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:52:11 +0100 Subject: [PATCH 27/76] Improve support for platforms without stddef.h. NULL definition should now be provided by architecture port file atomport.h, which in most cases can just include stddef.h. --- tests/timer5.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/timer5.c b/tests/timer5.c index 231882b..0082a47 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -32,7 +32,6 @@ #include "atomtimer.h" #include "atomtests.h" - /* Global test data */ static volatile int callback_ran_flag; From f686c6527a4269282b11dedbd4e874c2d2b796ed Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 26 May 2011 23:27:05 +0100 Subject: [PATCH 28/76] Remove unnecessary stdio.h dependencies --- kernel/atommutex.c | 3 --- kernel/atomqueue.c | 3 --- kernel/atomsem.c | 3 --- kernel/atomtimer.c | 3 --- 4 files changed, 12 deletions(-) diff --git a/kernel/atommutex.c b/kernel/atommutex.c index 6663e6e..e3543f3 100755 --- a/kernel/atommutex.c +++ b/kernel/atommutex.c @@ -100,9 +100,6 @@ * */ -#ifndef STAND_ALONE -#include -#endif #include "atom.h" #include "atommutex.h" diff --git a/kernel/atomqueue.c b/kernel/atomqueue.c index 97880a3..8ab0965 100755 --- a/kernel/atomqueue.c +++ b/kernel/atomqueue.c @@ -90,9 +90,6 @@ * */ -#ifndef STAND_ALONE -#include -#endif #include diff --git a/kernel/atomsem.c b/kernel/atomsem.c index 8cd0567..db1c2be 100755 --- a/kernel/atomsem.c +++ b/kernel/atomsem.c @@ -87,9 +87,6 @@ * */ -#ifndef STAND_ALONE -#include -#endif #include "atom.h" #include "atomsem.h" diff --git a/kernel/atomtimer.c b/kernel/atomtimer.c index cf3a4e7..3693295 100755 --- a/kernel/atomtimer.c +++ b/kernel/atomtimer.c @@ -66,9 +66,6 @@ * */ -#ifndef STAND_ALONE -#include -#endif #include "atom.h" From d5a8c186b0bc8c71ef716057d34274800f18e339 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 16:41:18 +0100 Subject: [PATCH 29/76] Add support for architectures with stack alignment requirements in preparation for various 32 bit ports. NOTE: The atomThreadCreate() and atmoOSInit() APIs have changed to take stack_bottom rather than stack_top and to allow optional stack-checking on a per-thread basis. --- kernel/atom.h | 6 ++-- kernel/atomkernel.c | 71 ++++++++++++++++++++++++-------------- kernel/atomport-template.h | 3 ++ ports/avr/atomport.h | 2 ++ ports/avr/tests-main.c | 21 ++++++----- ports/stm8/atomport.h | 2 ++ ports/stm8/tests-main.c | 7 ++-- tests/kern1.c | 12 +++---- tests/kern3.c | 8 ++--- tests/kern4.c | 16 ++++----- tests/mutex1.c | 8 ++--- tests/mutex2.c | 4 +-- tests/mutex3.c | 16 ++++----- tests/mutex4.c | 16 ++++----- tests/mutex5.c | 4 +-- tests/mutex6.c | 4 +-- tests/mutex7.c | 4 +-- tests/mutex8.c | 12 +++---- tests/mutex9.c | 4 +-- tests/queue2.c | 8 ++--- tests/queue3.c | 8 ++--- tests/queue5.c | 16 ++++----- tests/queue6.c | 4 +-- tests/queue7.c | 12 +++---- tests/queue9.c | 16 ++++----- tests/sem1.c | 8 ++--- tests/sem3.c | 16 ++++----- tests/sem4.c | 16 ++++----- tests/sem5.c | 4 +-- tests/sem6.c | 4 +-- tests/sem7.c | 4 +-- tests/sem8.c | 12 +++---- tests/sem9.c | 12 +++---- tests/timer2.c | 12 +++---- 34 files changed, 199 insertions(+), 173 deletions(-) diff --git a/kernel/atom.h b/kernel/atom.h index 870e8bb..b99512d 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -62,7 +62,7 @@ typedef struct atom_tcb /* Details used if thread stack-checking is required */ #ifdef ATOM_STACK_CHECKING - POINTER stack_top; /* Pointer to top of stack allocation */ + POINTER stack_bottom; /* Pointer to bottom of stack allocation */ uint32_t stack_size; /* Size of stack allocation in bytes */ #endif @@ -98,7 +98,7 @@ extern uint8_t atomOSStarted; /* Function prototypes */ -extern uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t stack_size); +extern uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check); extern void atomOSStart (void); extern void atomSched (uint8_t timer_tick); @@ -113,7 +113,7 @@ extern ATOM_TCB *tcbDequeuePriority (ATOM_TCB **tcb_queue_ptr, uint8_t priority) extern ATOM_TCB *atomCurrentContext (void); -extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size); +extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); extern ATOM_TCB *archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 9c0e276..91d0a58 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -369,25 +369,31 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) * new thread may be scheduled in before the function returns. * * Optionally prefills the thread stack with a known value to enable stack - * usage checking (if the ATOM_STACK_CHECKING macro is defined). + * usage checking (if the ATOM_STACK_CHECKING macro is defined and + * stack_check parameter is set to TRUE). * * @param[in] tcb_ptr Pointer to the thread's TCB storage * @param[in] priority Priority of the thread (0 to 255) * @param[in] entry_point Thread entry point * @param[in] entry_param Parameter passed to thread entry point - * @param[in] stack_top Top of the stack area + * @param[in] stack_bottom Bottom of the stack area * @param[in] stack_size Size of the stack area in bytes + * @param[in] stack_check TRUE to enable stack checking for this thread * * @retval ATOM_OK Success * @retval ATOM_ERR_PARAM Bad parameters * @retval ATOM_ERR_QUEUE Error putting the thread on the ready queue */ -uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_top, uint32_t stack_size) +uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check) { CRITICAL_STORE; uint8_t status; + uint8_t *stack_top; +#ifdef ATOM_STACK_CHECKING + int32_t count; +#endif - if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_top == NULL) + if ((tcb_ptr == NULL) || (entry_point == NULL) || (stack_bottom == NULL) || (stack_size == 0)) { /* Bad parameters */ @@ -411,6 +417,13 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin tcb_ptr->entry_point = entry_point; tcb_ptr->entry_param = entry_param; + /** + * Calculate a pointer to the topmost stack entry, suitably aligned + * for the architecture. This may discard the top few bytes if the + * stack size is not a multiple of the stack entry/alignment size. + */ + stack_top = (uint8_t *)stack_bottom + (stack_size & ~(STACK_ALIGN_SIZE - 1)) - STACK_ALIGN_SIZE; + /** * Additional processing only required if stack-checking is * enabled. Incurs a slight overhead on each thread creation @@ -418,25 +431,29 @@ uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_poin * compiled out if not desired. */ #ifdef ATOM_STACK_CHECKING - - /* Store the stack details for use by the stack-check function */ - tcb_ptr->stack_top = stack_top; - tcb_ptr->stack_size = stack_size; - - /** - * Prefill the stack with a known value. This is used later in - * calls to atomThreadStackCheck() to get an indication of how - * much stack has been used during runtime. - */ - while (stack_size > 0) + /* Set up stack-checking if enabled for this thread */ + if (stack_check) { - /* Initialise all stack bytes from bottom up to 0x5A */ - *((uint8_t *)stack_top - (stack_size - 1)) = STACK_CHECK_BYTE; - stack_size--; + /* Store the stack details for use by the stack-check function */ + tcb_ptr->stack_bottom = stack_bottom; + tcb_ptr->stack_size = stack_size; + + /** + * Prefill the stack with a known value. This is used later in + * calls to atomThreadStackCheck() to get an indication of how + * much stack has been used during runtime. + */ + count = (int32_t)stack_size; + while (count > 0) + { + /* Initialise all stack bytes from top down to 0x5A */ + *((uint8_t *)stack_bottom + (count - 1)) = STACK_CHECK_BYTE; + count--; + } } #else - /* Avoid compiler warnings due to unused stack_size variable */ - stack_size = stack_size; + /* Avoid compiler warning due to unused parameter */ + stack_check = stack_check; #endif /** @@ -528,10 +545,10 @@ uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t else { /** - * Starting at the far end, count the unmodified areas until a + * Starting at the bottom end, count the unmodified areas until a * modified byte is found. */ - stack_ptr = (uint8_t *)tcb_ptr->stack_top - (tcb_ptr->stack_size - 1); + stack_ptr = (uint8_t *)tcb_ptr->stack_bottom; for (i = 0; i < tcb_ptr->stack_size; i++) { /* Loop until a modified byte is found */ @@ -647,13 +664,14 @@ ATOM_TCB *atomCurrentContext (void) * operating system facilities are being initialised. They are normally * enabled by the archFirstThreadRestore() routine in the architecture port. * - * @param[in] idle_thread_stack_top Ptr to top of stack area for idle thread + * @param[in] idle_thread_stack_bottom Ptr to bottom of stack for idle thread * @param[in] idle_thread_stack_size Size of idle thread stack in bytes + * @param[in] idle_thread_stack_check TRUE if stack checking required on idle thread * * @retval ATOM_OK Success * @retval ATOM_ERROR Initialisation error */ -uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size) +uint8_t atomOSInit (void *idle_thread_stack_bottom, uint32_t idle_thread_stack_size, uint8_t idle_thread_stack_check) { uint8_t status; @@ -667,8 +685,9 @@ uint8_t atomOSInit (void *idle_thread_stack_top, uint32_t idle_thread_stack_size IDLE_THREAD_PRIORITY, atomIdleThread, 0, - idle_thread_stack_top, - idle_thread_stack_size); + idle_thread_stack_bottom, + idle_thread_stack_size, + idle_thread_stack_check); /* Return status */ return (status); diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 4f47cb4..68772e7 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -41,6 +41,9 @@ */ #define NULL ((void *)(0)) +/* Size of each stack entry / stack alignment size (e.g. 8 bits) */ +#define STACK_ALIGN_SIZE sizeof(unsigned char) + /** * Architecture-specific types. * Uses the stdint.h naming convention, so if stdint.h is available on the diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index 094e17e..ba4dead 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -43,6 +43,8 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/* Size of each stack entry / stack alignment size (8 bits on AVR) */ +#define STACK_ALIGN_SIZE sizeof(uint8_t) /** * Architecture-specific types. diff --git a/ports/avr/tests-main.c b/ports/avr/tests-main.c index 427cd93..9cb5596 100644 --- a/ports/avr/tests-main.c +++ b/ports/avr/tests-main.c @@ -71,7 +71,7 @@ * stack for application code local variables etc. * * With all OS tests implemented to date on the AVR, the Main thread - * stack has not exceeded 198 bytes. To allow all tests to run we set + * stack has not exceeded 201 bytes. To allow all tests to run we set * a minimum main thread stack size of 204 bytes. This may increase in * future as the codebase changes but for the time being is enough to * cope with all of the automated tests. @@ -167,17 +167,15 @@ int main ( void ) /** * Initialise the OS before creating our threads. * - * Note that we tell the OS that the idle stack is half its actual - * size. This prevents it prefilling the bottom half with known - * values for stack-checkig purposes, which we cannot allow because - * we are temporarily using it for our own stack. The remainder will - * still be available once the OS is started, this only prevents the - * OS from prefilling it. + * Note that we cannot enable stack-checking on the idle thread on + * this platform because we are already using part of the idle + * thread's stack now as our startup stack. Prefilling for stack + * checking would overwrite our current stack. * * If you are not reusing the idle thread's stack during startup then - * you should pass in the correct size here. + * you are free to enable stack-checking here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], (IDLE_STACK_SIZE_BYTES/2)); + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, FALSE); if (status == ATOM_OK) { /* Enable the system tick timer */ @@ -186,8 +184,9 @@ int main ( void ) /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], - MAIN_STACK_SIZE_BYTES); + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); if (status == ATOM_OK) { /** diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index bcd36e1..caf87de 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -45,6 +45,8 @@ /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 +/* Size of each stack entry / stack alignment size (8 bits on STM8) */ +#define STACK_ALIGN_SIZE sizeof(u8) /** * Architecture-specific types. diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index 460c4bc..21b6d4d 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -139,7 +139,7 @@ NO_REG_SAVE void main ( void ) */ /* Initialise the OS before creating our threads */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES - 1], IDLE_STACK_SIZE_BYTES); + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, TRUE); if (status == ATOM_OK) { /* Enable the system tick timer */ @@ -148,8 +148,9 @@ NO_REG_SAVE void main ( void ) /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES - 1], - MAIN_STACK_SIZE_BYTES); + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); if (status == ATOM_OK) { /** diff --git a/tests/kern1.c b/tests/kern1.c index 90a3991..0f09756 100644 --- a/tests/kern1.c +++ b/tests/kern1.c @@ -63,8 +63,8 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad TCB pointer */ if (atomThreadCreate (NULL, TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + &test_thread_stack[0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad TCB check\n")); failures++; @@ -72,8 +72,8 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad entry point */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, NULL, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + &test_thread_stack[0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad entry check\n")); failures++; @@ -81,7 +81,7 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad stack pointer */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0, - NULL, TEST_THREAD_STACK_SIZE) != ATOM_ERR_PARAM) + NULL, TEST_THREAD_STACK_SIZE, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad stack ptr check\n")); failures++; @@ -89,7 +89,7 @@ uint32_t test_start (void) /* atomThreadCreate: Pass a bad stack size */ if (atomThreadCreate (&tcb1, TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[TEST_THREAD_STACK_SIZE - 1], 0) != ATOM_ERR_PARAM) + &test_thread_stack[0], 0, TRUE) != ATOM_ERR_PARAM) { ATOMLOG (_STR("Bad stack size check\n")); failures++; diff --git a/tests/kern3.c b/tests/kern3.c index 555ac8e..4ff1caa 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -98,8 +98,8 @@ uint32_t test_start (void) /* Create low priority thread */ if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; @@ -107,8 +107,8 @@ uint32_t test_start (void) /* Create high priority thread */ else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; diff --git a/tests/kern4.c b/tests/kern4.c index eb39364..2a06e95 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -100,29 +100,29 @@ uint32_t test_start (void) * a spell in which this thread was run. */ if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; } else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { ATOMLOG (_STR("Bad thread create\n")); failures++; diff --git a/tests/mutex1.c b/tests/mutex1.c index 4a340d2..976a8ef 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -136,8 +136,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -199,8 +199,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/mutex2.c b/tests/mutex2.c index 5432ec3..df31d0e 100644 --- a/tests/mutex2.c +++ b/tests/mutex2.c @@ -143,8 +143,8 @@ uint32_t test_start (void) /* Create a test thread, the sole purpose of which is to own mutex2 */ g_owned = 0; if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); diff --git a/tests/mutex3.c b/tests/mutex3.c index 7a9b2da..b5e83a4 100644 --- a/tests/mutex3.c +++ b/tests/mutex3.c @@ -111,8 +111,8 @@ uint32_t test_start (void) { /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -124,8 +124,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -137,8 +137,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -150,8 +150,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex4.c b/tests/mutex4.c index cbfc7bf..5ecc316 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -100,8 +100,8 @@ uint32_t test_start (void) /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -112,8 +112,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -124,8 +124,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -136,8 +136,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex5.c b/tests/mutex5.c index a455fce..5125d96 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -94,8 +94,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex6.c b/tests/mutex6.c index 114ca52..b47b7aa 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -99,8 +99,8 @@ uint32_t test_start (void) /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex7.c b/tests/mutex7.c index 7d25fae..32c6452 100644 --- a/tests/mutex7.c +++ b/tests/mutex7.c @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/mutex8.c b/tests/mutex8.c index 6ea01f0..9b2af5c 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -103,8 +103,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -113,8 +113,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/mutex9.c b/tests/mutex9.c index 9e20b97..36cf965 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -87,8 +87,8 @@ uint32_t test_start (void) /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/queue2.c b/tests/queue2.c index e45a7db..e2ccff6 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -89,8 +89,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -146,8 +146,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/queue3.c b/tests/queue3.c index 932465a..dd7eb1a 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -106,8 +106,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is full */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -177,8 +177,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is full */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/queue5.c b/tests/queue5.c index 6ba450c..ef303ce 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -114,8 +114,8 @@ uint32_t test_start (void) /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -127,8 +127,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -140,8 +140,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -153,8 +153,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/queue6.c b/tests/queue6.c index b50bc63..68e43a2 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -106,8 +106,8 @@ uint32_t test_start (void) /* Create a test thread that will block because the queue is empty */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO + 1, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); diff --git a/tests/queue7.c b/tests/queue7.c index e6cca06..061bc20 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -103,8 +103,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -113,8 +113,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/queue9.c b/tests/queue9.c index 8091bf4..09ed14f 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -102,8 +102,8 @@ uint32_t test_start (void) { /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -114,8 +114,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -126,8 +126,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -138,8 +138,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem1.c b/tests/sem1.c index 54b7ddc..6842cd2 100644 --- a/tests/sem1.c +++ b/tests/sem1.c @@ -133,8 +133,8 @@ uint32_t test_start (void) } else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test1_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -200,8 +200,8 @@ uint32_t test_start (void) failures++; } else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test2_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); diff --git a/tests/sem3.c b/tests/sem3.c index d3d83f7..33e06ad 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -102,8 +102,8 @@ uint32_t test_start (void) { /* Create Thread 1 (lower priority thread A) */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO+1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -115,8 +115,8 @@ uint32_t test_start (void) /* Create Thread 2 (lower priority thread B) */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO+1, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -128,8 +128,8 @@ uint32_t test_start (void) /* Create Thread 3 (higher priority thread A) */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -141,8 +141,8 @@ uint32_t test_start (void) /* Create Thread 4 (higher priority thread B) */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem4.c b/tests/sem4.c index 64ad00e..193b1e2 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -96,8 +96,8 @@ uint32_t test_start (void) { /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -108,8 +108,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -120,8 +120,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); @@ -132,8 +132,8 @@ uint32_t test_start (void) /* Create Thread 4 */ if (atomThreadCreate(&tcb[3], TEST_THREAD_PRIO, test_thread_func, 4, - &test_thread_stack[3][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem5.c b/tests/sem5.c index 3b7daa7..6a00750 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -83,8 +83,8 @@ uint32_t test_start (void) { /* Create second thread */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem6.c b/tests/sem6.c index f579f8e..7aebda1 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -93,8 +93,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem7.c b/tests/sem7.c index c574e7c..337a7b5 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -99,8 +99,8 @@ uint32_t test_start (void) /* Create second thread */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread\n")); diff --git a/tests/sem8.c b/tests/sem8.c index 59ee7a7..5f2ecea 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -109,8 +109,8 @@ uint32_t test_start (void) /* Create thread 1: Higher priority than main thread so should sleep */ else if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO - 1, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -119,8 +119,8 @@ uint32_t test_start (void) /* Create thread 2: Same priority as main thread so should not sleep */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -129,8 +129,8 @@ uint32_t test_start (void) /* Create thread 3: Same priority as main thread so should not sleep */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/sem9.c b/tests/sem9.c index 30fc0a0..f2f6c55 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -86,8 +86,8 @@ uint32_t test_start (void) { /* Create test thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 0, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 1\n")); @@ -96,8 +96,8 @@ uint32_t test_start (void) /* Create test thread 2 */ else if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 2\n")); @@ -106,8 +106,8 @@ uint32_t test_start (void) /* Create test thread 3 */ else if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Error creating test thread 3\n")); diff --git a/tests/timer2.c b/tests/timer2.c index 883066e..e75defc 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -72,8 +72,8 @@ uint32_t test_start (void) /* Create Thread 1 */ if (atomThreadCreate(&tcb[0], TEST_THREAD_PRIO, test_thread_func, 1, - &test_thread_stack[0][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread1\n")); @@ -82,8 +82,8 @@ uint32_t test_start (void) /* Create Thread 2 */ if (atomThreadCreate(&tcb[1], TEST_THREAD_PRIO, test_thread_func, 2, - &test_thread_stack[1][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread2\n")); @@ -92,8 +92,8 @@ uint32_t test_start (void) /* Create Thread 3 */ if (atomThreadCreate(&tcb[2], TEST_THREAD_PRIO, test_thread_func, 3, - &test_thread_stack[2][TEST_THREAD_STACK_SIZE - 1], - TEST_THREAD_STACK_SIZE) != ATOM_OK) + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) { /* Fail */ ATOMLOG (_STR("Thread3\n")); From 9237406b123e88f61eb4be4424473ea4f81857a6 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:15:38 +0100 Subject: [PATCH 30/76] AVR flash-program now checks sizes against the architecture. --- ports/avr/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ports/avr/Makefile b/ports/avr/Makefile index c5f214b..7fdb5c4 100644 --- a/ports/avr/Makefile +++ b/ports/avr/Makefile @@ -112,7 +112,7 @@ clean: # Send to STK500 program : $(BUILD_DIR)/$(app).hex - $(SIZE) -C $(BUILD_DIR)/$(app).elf + $(SIZE) -C --mcu=$(PART) $(BUILD_DIR)/$(app).elf $(UISP) -dprog=stk500 -dserial=$(UISP_DEV) -dpart=$(PART) --erase --upload --verify if=$(BUILD_DIR)/$(app).hex doxygen: From c0e238ffb23cc8c49b981763fa0370f9cc5a712d Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:16:48 +0100 Subject: [PATCH 31/76] Reduce BSS size in queue5 and queue9 module - brings the BSS on ATmega16 to just under 1KB, allowing those tests to be run on that target. --- tests/queue5.c | 2 +- tests/queue9.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/queue5.c b/tests/queue5.c index ef303ce..a3c15d9 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -33,7 +33,7 @@ /* Number of queue entries */ -#define QUEUE_ENTRIES 8 +#define QUEUE_ENTRIES 4 /* Number of test threads */ diff --git a/tests/queue9.c b/tests/queue9.c index 09ed14f..0907928 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -38,7 +38,7 @@ /* Test queue size */ -#define QUEUE_ENTRIES 8 +#define QUEUE_ENTRIES 4 /* Number of test threads */ From d06cbdc16a317f32ff6a62044a338dba97431f33 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 27 May 2011 17:35:56 +0100 Subject: [PATCH 32/76] Add comments to critical region regarding nesting requirement. --- kernel/atomport-template.h | 7 ++++++- ports/avr/atomport.h | 7 ++++++- ports/stm8/atomport.h | 7 ++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 68772e7..9f17635 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -60,7 +60,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ #define CRITICAL_STORE uint8_t sreg #define CRITICAL_START() sreg = SREG; cli(); #define CRITICAL_END() SREG = sreg diff --git a/ports/avr/atomport.h b/ports/avr/atomport.h index ba4dead..875bd15 100644 --- a/ports/avr/atomport.h +++ b/ports/avr/atomport.h @@ -54,7 +54,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ #define CRITICAL_STORE uint8_t sreg #define CRITICAL_START() sreg = SREG; cli(); #define CRITICAL_END() SREG = sreg diff --git a/ports/stm8/atomport.h b/ports/stm8/atomport.h index caf87de..2063bfb 100644 --- a/ports/stm8/atomport.h +++ b/ports/stm8/atomport.h @@ -60,7 +60,12 @@ #define POINTER void * -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ /* COSMIC: Use inline assembler */ #if defined(__CSMC__) From 9a4dac8c761dacdd0d4da19ff1c06d90f7b649c0 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 33/76] Compilable MIPS code. Signed-off-by: Himanshu Chauhan --- tests/test-template.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test-template.c b/tests/test-template.c index c306c1c..9f00f38 100644 --- a/tests/test-template.c +++ b/tests/test-template.c @@ -53,4 +53,4 @@ uint32_t test_start (void) /* Quit */ return failures; -} \ No newline at end of file +} From fe6232c981ef7f2eb13888897cd51655852bb547 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Fri, 20 May 2011 09:22:05 +0530 Subject: [PATCH 34/76] Half way debug code of context switching. Main thread comes up but the secondary threads doesn't get scheduled. Signed-off-by: Himanshu Chauhan --- ports/mips/tests-main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 6a9cabc..ac747f1 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -120,6 +120,7 @@ /* Application threads' TCBs */ static ATOM_TCB main_tcb; +static ATOM_TCB secondary_tcb; /* Main thread's stack area */ static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); @@ -129,6 +130,7 @@ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned ( /* Forward declarations */ static void main_thread_func (uint32_t data); +static void secondary_thread_func (uint32_t data); /** * \b main From 4fbbe465ee9a4d2067b6877eee4b440d52802ee2 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Wed, 25 May 2011 23:52:11 +0100 Subject: [PATCH 35/76] Improve support for platforms without stddef.h. NULL definition should now be provided by architecture port file atomport.h, which in most cases can just include stddef.h. --- kernel/atomport-template.h | 1 - 1 file changed, 1 deletion(-) diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index 9f17635..ecb07ea 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -30,7 +30,6 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H - /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 From c7bc5cf3964be87de53a353838a55f136302ef22 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 19 May 2011 19:07:53 +0530 Subject: [PATCH 36/76] Change related to upstream merge. * STAND_ALONE conditional compilation is removed. * Previous interim commits are squashed. * printk.h is included from atomport.h * atom-types.h and atommport-types.h have been removed. Signed-off-by: Himanshu Chauhan --- kernel/atomsem.c | 6 ++++++ tests/test-template.c | 1 - 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/kernel/atomsem.c b/kernel/atomsem.c index db1c2be..9d1bab5 100755 --- a/kernel/atomsem.c +++ b/kernel/atomsem.c @@ -87,6 +87,12 @@ * */ +<<<<<<< HEAD +======= +#ifndef STAND_ALONE +#include +#endif +>>>>>>> Change related to upstream merge. #include "atom.h" #include "atomsem.h" diff --git a/tests/test-template.c b/tests/test-template.c index 9f00f38..449af59 100644 --- a/tests/test-template.c +++ b/tests/test-template.c @@ -31,7 +31,6 @@ #include "atom.h" #include "atomtests.h" - /** * \b test_start * From 8dfd1f4c0f21a3c4fd5b4cff48454015e25e1e80 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Sat, 28 May 2011 10:02:43 +0530 Subject: [PATCH 37/76] Deleting atom-types.h not required anymore. Signed-off-by: Himanshu Chauhan --- kernel/atom-types.h | 37 ------------------------------------- 1 file changed, 37 deletions(-) delete mode 100755 kernel/atom-types.h diff --git a/kernel/atom-types.h b/kernel/atom-types.h deleted file mode 100755 index 898e2ca..0000000 --- a/kernel/atom-types.h +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_TYPES_H -#define __ATOM_TYPES_H - -#include - -#define NULL ((void *)(0)) - -#endif /* __ATOM_TYPES_H */ From 546990788d1836cb72edec0799b49d5a4695f596 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Sat, 28 May 2011 17:28:21 +0100 Subject: [PATCH 38/76] Use info@atomthreads.com email address throughout documentation. --- README | 2 +- kernel/README | 20 ++++++++++---------- ports/avr/README | 2 +- ports/stm8/README-COSMIC | 2 +- ports/stm8/README-IAR | 2 +- ports/stm8/README-RAISONANCE | 2 +- tests/README | 22 +++++++++++----------- 7 files changed, 26 insertions(+), 26 deletions(-) diff --git a/README b/README index 79ab9b2..b88b6b4 100644 --- a/README +++ b/README @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- Library: Atomthreads -Author: Kelvin Lawson +Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised diff --git a/kernel/README b/kernel/README index 3d33f3f..ecec7d4 100644 --- a/kernel/README +++ b/kernel/README @@ -1,11 +1,11 @@ ---------------------------------------------------------------------------- - -Library: Atomthreads -Author: Kelvin Lawson -Website: http://atomthreads.com -License: BSD Revised - ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- + +Library: Atomthreads +Author: Kelvin Lawson +Website: http://atomthreads.com +License: BSD Revised + +--------------------------------------------------------------------------- KERNEL SOURCES @@ -21,12 +21,12 @@ Each module source file contains detailed documentation including an introduction to usage of the module and full descriptions of each API. Refer to the sources for further documentation. ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- BUILDING THE KERNEL The kernel is built from the architecture port folder. Build instructions are included in the README file for each port. ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- diff --git a/ports/avr/README b/ports/avr/README index df61880..e73fa4c 100644 --- a/ports/avr/README +++ b/ports/avr/README @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- Library: Atomthreads -Author: Kelvin Lawson +Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised diff --git a/ports/stm8/README-COSMIC b/ports/stm8/README-COSMIC index cae78f3..94e2bc5 100644 --- a/ports/stm8/README-COSMIC +++ b/ports/stm8/README-COSMIC @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- Library: Atomthreads -Author: Kelvin Lawson +Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised diff --git a/ports/stm8/README-IAR b/ports/stm8/README-IAR index 9e82acd..9225e07 100644 --- a/ports/stm8/README-IAR +++ b/ports/stm8/README-IAR @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- Library: Atomthreads -Author: Kelvin Lawson +Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised diff --git a/ports/stm8/README-RAISONANCE b/ports/stm8/README-RAISONANCE index 8eef2cd..c99b90c 100644 --- a/ports/stm8/README-RAISONANCE +++ b/ports/stm8/README-RAISONANCE @@ -1,7 +1,7 @@ --------------------------------------------------------------------------- Library: Atomthreads -Author: Kelvin Lawson +Author: Kelvin Lawson Website: http://atomthreads.com License: BSD Revised diff --git a/tests/README b/tests/README index e343a7a..35c23a7 100644 --- a/tests/README +++ b/tests/README @@ -1,11 +1,11 @@ ---------------------------------------------------------------------------- - -Library: Atomthreads -Author: Kelvin Lawson -Website: http://atomthreads.com -License: BSD Revised - ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- + +Library: Atomthreads +Author: Kelvin Lawson +Website: http://atomthreads.com +License: BSD Revised + +--------------------------------------------------------------------------- AUTOMATED TEST SUITE @@ -20,7 +20,7 @@ Developers of new CPU architecture ports can take advantage of the thorough coverage provided by these tests to considerably speed up development and validation time. ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- HOW TO RUN THE TESTS @@ -29,7 +29,7 @@ folder. Instructions are included in the README file for each port, which describes the process for building test applications as well as downloading to and running the tests on the target device. ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- WRITING ADDITIONAL TESTS @@ -50,5 +50,5 @@ modules which do not consume large amounts of processor resource. For example the number of test threads should ideally be kept low in order to allow smaller systems to accommodate the thread stack requirements. ---------------------------------------------------------------------------- +--------------------------------------------------------------------------- From b9931b4c3874b619a353e46d39a389dfd5c44fb0 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Sun, 29 May 2011 09:01:23 +0530 Subject: [PATCH 39/76] Changes rebased to lastest API changes for STACK_ALIGN Signed-off-by: Himanshu Chauhan --- ports/mips/Makefile | 3 +-- ports/mips/atomport.h | 51 +++++++++++++++++++++++++++-------------- ports/mips/tests-main.c | 13 +++++++---- 3 files changed, 44 insertions(+), 23 deletions(-) diff --git a/ports/mips/Makefile b/ports/mips/Makefile index aae07df..f92b505 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -75,8 +75,7 @@ CFLAGS= -g \ -finline-functions \ -nostdinc \ -fno-builtin \ - -fno-stack-protector \ - -DSTAND_ALONE + -fno-stack-protector # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 679cc85..64ba0bc 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -42,7 +42,7 @@ typedef long long int64_t; typedef unsigned long size_t; #define UINT32 uint32_t - +#define STACK_ALIGN_SIZE sizeof(uint32_t) #define NULL ((void *)(0)) /** @@ -54,23 +54,40 @@ typedef unsigned long size_t; #include "printk.h" -/* Critical region protection */ -#define CRITICAL_STORE unsigned int status_reg -#define CRITICAL_START() \ - __asm__ __volatile__("di %0\t\n" \ - "ssnop\t\n" \ - "ssnop\t\n" \ - "ssnop\t\n" \ - "ehb\t\n" \ - :"=r"(status_reg)); +extern uint32_t at_preempt_count; -#define CRITICAL_END() \ - __asm__ __volatile__("ei %0\t\n" \ - "ssnop\t\n" \ - "ssnop\t\n" \ - "ssnop\t\n" \ - "ehb\t\n" \ - ::"r"(status_reg)); +/* Critical region protection */ +#define CRITICAL_STORE uint32_t status_reg +#define CRITICAL_START() \ + do { \ + extern uint32_t at_preempt_count; \ + __asm__ __volatile__("di %0\t\n" \ + "ehb\t\n" \ + :"=r"(status_reg)); \ + at_preempt_count++; \ + }while(0); + +#define CRITICAL_END() \ + do { \ + extern uint32_t at_preempt_count; \ + if (at_preempt_count == 0) { \ + printk("BUG: Preempt count is zero!\n"); \ + for(;;); \ + } \ + at_preempt_count--; \ + \ + if (at_preempt_count == 0) { \ + if (atomCurrentContext()) { \ + printk("+"); \ + __asm__ __volatile__("ei %0\t\n" \ + "ehb\t\n" \ + ::"r"(status_reg));\ + } else { \ + printk("."); \ + } \ + } \ + \ + }while(0); /* Uncomment to enable stack-checking */ /* #define ATOM_STACK_CHECKING */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 6a9cabc..57347aa 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -130,6 +130,9 @@ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned ( /* Forward declarations */ static void main_thread_func (uint32_t data); +/* Global Data */ +uint32_t at_preempt_count; + /** * \b main * @@ -143,6 +146,8 @@ int main ( void ) { int8_t status; + at_preempt_count = 0; + /** * Note: to protect OS structures and data during initialisation, * interrupts must remain disabled until the first thread @@ -164,8 +169,8 @@ int main ( void ) * If you are not reusing the idle thread's stack during startup then * you should pass in the correct size here. */ - status = atomOSInit(&idle_thread_stack[IDLE_STACK_SIZE_BYTES], - IDLE_STACK_SIZE_BYTES); + status = atomOSInit(&idle_thread_stack[0], + IDLE_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { /* FIXME: Enable the system tick timer */ @@ -175,8 +180,8 @@ int main ( void ) /* Create an application thread */ status = atomThreadCreate(&main_tcb, TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[MAIN_STACK_SIZE_BYTES], - MAIN_STACK_SIZE_BYTES); + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { mips_cpu_timer_enable(); From 711ce0e4695fbc35c242e0819e184334f37ae59a Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Thu, 2 Jun 2011 20:15:11 +0530 Subject: [PATCH 40/76] Changed the default stack size for threads. Fixed the critical section problems. Signed-off-by: Himanshu Chauhan --- ports/mips/atomport-asm.s | 10 ++++++++++ ports/mips/atomport-tests.h | 2 +- ports/mips/atomport.h | 3 --- ports/mips/tests-main.c | 6 +++--- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index 53cff5b..2b64746 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -32,6 +32,8 @@ .section .text .extern atomCurrentContext +.extern at_preempt_count + /** * Function that performs the contextSwitch. Whether its a voluntary release * of CPU by thread or a pre-emption, under both conditions this function is @@ -145,7 +147,15 @@ __unwind_int_context: RESTORE_INT_CONTEXT __ret_from_switch: + la k0, at_preempt_count + lw k1, (k0) + addi k1, k1, -1 + sw k1, (k0) + bnez k1, __return_from_int + nop enable_global_interrupts + ehb +__return_from_int: eret /** diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h index 66b58eb..b6b6c46 100644 --- a/ports/mips/atomport-tests.h +++ b/ports/mips/atomport-tests.h @@ -39,7 +39,7 @@ #define _STR /* Default thread stack size (in bytes) */ -#define TEST_THREAD_STACK_SIZE 128 +#define TEST_THREAD_STACK_SIZE 8192 /* Uncomment to enable logging of stack usage to UART */ /* #define TESTS_LOG_STACK_USAGE */ diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index 64ba0bc..a6ed705 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -78,12 +78,9 @@ extern uint32_t at_preempt_count; \ if (at_preempt_count == 0) { \ if (atomCurrentContext()) { \ - printk("+"); \ __asm__ __volatile__("ei %0\t\n" \ "ehb\t\n" \ ::"r"(status_reg));\ - } else { \ - printk("."); \ } \ } \ \ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c index 57347aa..27aee97 100644 --- a/ports/mips/tests-main.c +++ b/ports/mips/tests-main.c @@ -48,7 +48,7 @@ * In this case, the idle stack is allocated on the BSS via the * idle_thread_stack[] byte array. */ -#define IDLE_STACK_SIZE_BYTES 4096 +#define IDLE_STACK_SIZE_BYTES 8192 /* @@ -122,10 +122,10 @@ static ATOM_TCB main_tcb; /* Main thread's stack area */ -static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES] __attribute__((aligned (4))); +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; /* Idle thread's stack area */ -static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES] __attribute__((aligned (4))); +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; /* Forward declarations */ static void main_thread_func (uint32_t data); From fae8dd7516eb43111736079b7884519136a044ee Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 2 Jun 2011 22:12:56 +0100 Subject: [PATCH 41/76] Formatting changes only. --- ports/avr/tests-main.c | 4 ++-- ports/stm8/tests-main.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ports/avr/tests-main.c b/ports/avr/tests-main.c index 9cb5596..a634167 100644 --- a/ports/avr/tests-main.c +++ b/ports/avr/tests-main.c @@ -245,7 +245,7 @@ static void main_thread_func (uint32_t data) stdout = &uart_stdout; /* Put a message out on the UART */ - printf_P(PSTR("Go\n")); + printf_P (PSTR("Go\n")); /* Start test. All tests use the same start API. */ test_status = test_start(); @@ -295,7 +295,7 @@ static void main_thread_func (uint32_t data) PORTB ^= (1 << 7); /* Sleep then toggle LED again */ - atomTimerDelay(sleep_ticks); + atomTimerDelay (sleep_ticks); } } diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index 21b6d4d..6b24bf2 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -201,7 +201,7 @@ static void main_thread_func (uint32_t param) } /* Put a message out on the UART */ - printf("Go\n"); + printf ("Go\n"); /* Start test. All tests use the same start API. */ test_status = test_start(); @@ -255,7 +255,7 @@ static void main_thread_func (uint32_t param) GPIO_WriteReverse(GPIOD, GPIO_PIN_0); /* Sleep then toggle LED again */ - atomTimerDelay(sleep_ticks); + atomTimerDelay (sleep_ticks); } } From 7bc40f9d62029540bc30d1870a29fe34fba77e32 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 2 Jun 2011 22:23:57 +0100 Subject: [PATCH 42/76] Formatting changes. --- ports/avr/tests-main.c | 2 +- ports/stm8/tests-main.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/avr/tests-main.c b/ports/avr/tests-main.c index a634167..c8c9abb 100644 --- a/ports/avr/tests-main.c +++ b/ports/avr/tests-main.c @@ -186,7 +186,7 @@ int main ( void ) TEST_THREAD_PRIO, main_thread_func, 0, &main_thread_stack[0], MAIN_STACK_SIZE_BYTES, - TRUE); + TRUE); if (status == ATOM_OK) { /** diff --git a/ports/stm8/tests-main.c b/ports/stm8/tests-main.c index 6b24bf2..7981a19 100644 --- a/ports/stm8/tests-main.c +++ b/ports/stm8/tests-main.c @@ -150,7 +150,7 @@ NO_REG_SAVE void main ( void ) TEST_THREAD_PRIO, main_thread_func, 0, &main_thread_stack[0], MAIN_STACK_SIZE_BYTES, - TRUE); + TRUE); if (status == ATOM_OK) { /** From ac0643a9598c2158a0f9b9033dc53c43164a7afa Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 2 Jun 2011 22:32:49 +0100 Subject: [PATCH 43/76] First draft of MIPS port from Himanshu. Some local mods to more closely resemble the headers and layout of the AVR and STM8 ports. --- ports/mips/.gdbinit | 1 + ports/mips/8250-serial.c | 74 ++ ports/mips/8250-serial.h | 346 +++++++++ ports/mips/Doxyfile | 1161 ++++++++++++++++++++++++++++++ ports/mips/Makefile | 140 ++++ ports/mips/README | 3 + ports/mips/atomport-asm-macros.h | 283 ++++++++ ports/mips/atomport-asm.s | 186 +++++ ports/mips/atomport-entry.s | 161 +++++ ports/mips/atomport-interrupts.c | 58 ++ ports/mips/atomport-interrupts.h | 38 + ports/mips/atomport-private.h | 36 + ports/mips/atomport-tests.h | 51 ++ ports/mips/atomport-timer.c | 67 ++ ports/mips/atomport.c | 82 +++ ports/mips/atomport.h | 96 +++ ports/mips/io.c | 44 ++ ports/mips/linker.ld | 74 ++ ports/mips/printk.c | 59 ++ ports/mips/printk.h | 42 ++ ports/mips/regs.h | 144 ++++ ports/mips/stdarg.h | 28 + ports/mips/string.c | 61 ++ ports/mips/string.h | 42 ++ ports/mips/system.h | 52 ++ ports/mips/tests-main.c | 260 +++++++ ports/mips/vsprintf.c | 244 +++++++ 27 files changed, 3833 insertions(+) create mode 100644 ports/mips/.gdbinit create mode 100644 ports/mips/8250-serial.c create mode 100644 ports/mips/8250-serial.h create mode 100644 ports/mips/Doxyfile create mode 100644 ports/mips/Makefile create mode 100644 ports/mips/README create mode 100644 ports/mips/atomport-asm-macros.h create mode 100644 ports/mips/atomport-asm.s create mode 100644 ports/mips/atomport-entry.s create mode 100644 ports/mips/atomport-interrupts.c create mode 100644 ports/mips/atomport-interrupts.h create mode 100644 ports/mips/atomport-private.h create mode 100644 ports/mips/atomport-tests.h create mode 100644 ports/mips/atomport-timer.c create mode 100644 ports/mips/atomport.c create mode 100644 ports/mips/atomport.h create mode 100644 ports/mips/io.c create mode 100755 ports/mips/linker.ld create mode 100644 ports/mips/printk.c create mode 100644 ports/mips/printk.h create mode 100644 ports/mips/regs.h create mode 100755 ports/mips/stdarg.h create mode 100644 ports/mips/string.c create mode 100644 ports/mips/string.h create mode 100644 ports/mips/system.h create mode 100644 ports/mips/tests-main.c create mode 100644 ports/mips/vsprintf.c diff --git a/ports/mips/.gdbinit b/ports/mips/.gdbinit new file mode 100644 index 0000000..24efe1e --- /dev/null +++ b/ports/mips/.gdbinit @@ -0,0 +1 @@ +target remote localhost:1234 diff --git a/ports/mips/8250-serial.c b/ports/mips/8250-serial.c new file mode 100644 index 0000000..8d155dd --- /dev/null +++ b/ports/mips/8250-serial.c @@ -0,0 +1,74 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include +#include <8250-serial.h> + +#define PORT1 (void *)0xc00003f8 + +static inline unsigned int serial_in(int offset) +{ + return ioreadb(PORT1 + offset); +} + +static inline void serial_out(int offset, int value) +{ + iowriteb(PORT1 + offset, value); +} + +void putch(uint8_t c) +{ + while ((serial_in(UART_LSR) & UART_LSR_THRE) == 0) + ; + + serial_out(UART_TX, c); +} + +void init_console() +{ + serial_out(1 , 0); /* Turn off interrupts */ + + /* Communication Settings */ + serial_out(3 , 0x80); /* SET DLAB ON */ + serial_out(0 , 0x01); /* Set Baud rate - Divisor Latch Low Byte */ + /* 0x03 = 38,400 BPS */ + /* Default 0x01 = 115,200 BPS */ + /* 0x02 = 57,600 BPS */ + /* 0x06 = 19,200 BPS */ + /* 0x0C = 9,600 BPS */ + /* 0x18 = 4,800 BPS */ + /* 0x30 = 2,400 BPS */ + serial_out(1 , 0x00); /* Set Baud rate - Divisor Latch High Byte */ + serial_out(3 , 0x03); /* 8 Bits, No Parity, 1 Stop Bit */ + serial_out(2 , 0xC7); /* FIFO Control Register */ + serial_out(4 , 0x0B); /* Turn on DTR, RTS, and OUT2 */ +} diff --git a/ports/mips/8250-serial.h b/ports/mips/8250-serial.h new file mode 100644 index 0000000..c7907a1 --- /dev/null +++ b/ports/mips/8250-serial.h @@ -0,0 +1,346 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _8250_SERIAL_H +#define _8250_SERIAL_H + +/* + * DLAB=0 + */ +#define UART_RX 0 /* In: Receive buffer */ +#define UART_TX 0 /* Out: Transmit buffer */ + +#define UART_IER 1 /* Out: Interrupt Enable Register */ +#define UART_IER_MSI 0x08 /* Enable Modem status interrupt */ +#define UART_IER_RLSI 0x04 /* Enable receiver line status interrupt */ +#define UART_IER_THRI 0x02 /* Enable Transmitter holding register int. */ +#define UART_IER_RDI 0x01 /* Enable receiver data interrupt */ +/* + * Sleep mode for ST16650 and TI16750. For the ST16650, EFR[4]=1 + */ +#define UART_IERX_SLEEP 0x10 /* Enable sleep mode */ + +#define UART_IIR 2 /* In: Interrupt ID Register */ +#define UART_IIR_NO_INT 0x01 /* No interrupts pending */ +#define UART_IIR_ID 0x06 /* Mask for the interrupt ID */ +#define UART_IIR_MSI 0x00 /* Modem status interrupt */ +#define UART_IIR_THRI 0x02 /* Transmitter holding register empty */ +#define UART_IIR_RDI 0x04 /* Receiver data interrupt */ +#define UART_IIR_RLSI 0x06 /* Receiver line status interrupt */ + +#define UART_IIR_BUSY 0x07 /* DesignWare APB Busy Detect */ + +#define UART_FCR 2 /* Out: FIFO Control Register */ +#define UART_FCR_ENABLE_FIFO 0x01 /* Enable the FIFO */ +#define UART_FCR_CLEAR_RCVR 0x02 /* Clear the RCVR FIFO */ +#define UART_FCR_CLEAR_XMIT 0x04 /* Clear the XMIT FIFO */ +#define UART_FCR_DMA_SELECT 0x08 /* For DMA applications */ +/* + * Note: The FIFO trigger levels are chip specific: + * RX:76 = 00 01 10 11 TX:54 = 00 01 10 11 + * PC16550D: 1 4 8 14 xx xx xx xx + * TI16C550A: 1 4 8 14 xx xx xx xx + * TI16C550C: 1 4 8 14 xx xx xx xx + * ST16C550: 1 4 8 14 xx xx xx xx + * ST16C650: 8 16 24 28 16 8 24 30 PORT_16650V2 + * NS16C552: 1 4 8 14 xx xx xx xx + * ST16C654: 8 16 56 60 8 16 32 56 PORT_16654 + * TI16C750: 1 16 32 56 xx xx xx xx PORT_16750 + * TI16C752: 8 16 56 60 8 16 32 56 + */ +#define UART_FCR_R_TRIG_00 0x00 +#define UART_FCR_R_TRIG_01 0x40 +#define UART_FCR_R_TRIG_10 0x80 +#define UART_FCR_R_TRIG_11 0xc0 +#define UART_FCR_T_TRIG_00 0x00 +#define UART_FCR_T_TRIG_01 0x10 +#define UART_FCR_T_TRIG_10 0x20 +#define UART_FCR_T_TRIG_11 0x30 + +#define UART_FCR_TRIGGER_MASK 0xC0 /* Mask for the FIFO trigger range */ +#define UART_FCR_TRIGGER_1 0x00 /* Mask for trigger set at 1 */ +#define UART_FCR_TRIGGER_4 0x40 /* Mask for trigger set at 4 */ +#define UART_FCR_TRIGGER_8 0x80 /* Mask for trigger set at 8 */ +#define UART_FCR_TRIGGER_14 0xC0 /* Mask for trigger set at 14 */ +/* 16650 definitions */ +#define UART_FCR6_R_TRIGGER_8 0x00 /* Mask for receive trigger set at 1 */ +#define UART_FCR6_R_TRIGGER_16 0x40 /* Mask for receive trigger set at 4 */ +#define UART_FCR6_R_TRIGGER_24 0x80 /* Mask for receive trigger set at 8 */ +#define UART_FCR6_R_TRIGGER_28 0xC0 /* Mask for receive trigger set at 14 */ +#define UART_FCR6_T_TRIGGER_16 0x00 /* Mask for transmit trigger set at 16 */ +#define UART_FCR6_T_TRIGGER_8 0x10 /* Mask for transmit trigger set at 8 */ +#define UART_FCR6_T_TRIGGER_24 0x20 /* Mask for transmit trigger set at 24 */ +#define UART_FCR6_T_TRIGGER_30 0x30 /* Mask for transmit trigger set at 30 */ +#define UART_FCR7_64BYTE 0x20 /* Go into 64 byte mode (TI16C750) */ + +#define UART_LCR 3 /* Out: Line Control Register */ +/* + * Note: if the word length is 5 bits (UART_LCR_WLEN5), then setting + * UART_LCR_STOP will select 1.5 stop bits, not 2 stop bits. + */ +#define UART_LCR_DLAB 0x80 /* Divisor latch access bit */ +#define UART_LCR_SBC 0x40 /* Set break control */ +#define UART_LCR_SPAR 0x20 /* Stick parity (?) */ +#define UART_LCR_EPAR 0x10 /* Even parity select */ +#define UART_LCR_PARITY 0x08 /* Parity Enable */ +#define UART_LCR_STOP 0x04 /* Stop bits: 0=1 bit, 1=2 bits */ +#define UART_LCR_WLEN5 0x00 /* Wordlength: 5 bits */ +#define UART_LCR_WLEN6 0x01 /* Wordlength: 6 bits */ +#define UART_LCR_WLEN7 0x02 /* Wordlength: 7 bits */ +#define UART_LCR_WLEN8 0x03 /* Wordlength: 8 bits */ + +#define UART_MCR 4 /* Out: Modem Control Register */ +#define UART_MCR_CLKSEL 0x80 /* Divide clock by 4 (TI16C752, EFR[4]=1) */ +#define UART_MCR_TCRTLR 0x40 /* Access TCR/TLR (TI16C752, EFR[4]=1) */ +#define UART_MCR_XONANY 0x20 /* Enable Xon Any (TI16C752, EFR[4]=1) */ +#define UART_MCR_AFE 0x20 /* Enable auto-RTS/CTS (TI16C550C/TI16C750) */ +#define UART_MCR_LOOP 0x10 /* Enable loopback test mode */ +#define UART_MCR_OUT2 0x08 /* Out2 complement */ +#define UART_MCR_OUT1 0x04 /* Out1 complement */ +#define UART_MCR_RTS 0x02 /* RTS complement */ +#define UART_MCR_DTR 0x01 /* DTR complement */ + +#define UART_LSR 5 /* In: Line Status Register */ +#define UART_LSR_TEMT 0x40 /* Transmitter empty */ +#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ +#define UART_LSR_BI 0x10 /* Break interrupt indicator */ +#define UART_LSR_FE 0x08 /* Frame error indicator */ +#define UART_LSR_PE 0x04 /* Parity error indicator */ +#define UART_LSR_OE 0x02 /* Overrun error indicator */ +#define UART_LSR_DR 0x01 /* Receiver data ready */ +#define UART_LSR_BRK_ERROR_BITS 0x1E /* BI, FE, PE, OE bits */ + +#define UART_MSR 6 /* In: Modem Status Register */ +#define UART_MSR_DCD 0x80 /* Data Carrier Detect */ +#define UART_MSR_RI 0x40 /* Ring Indicator */ +#define UART_MSR_DSR 0x20 /* Data Set Ready */ +#define UART_MSR_CTS 0x10 /* Clear to Send */ +#define UART_MSR_DDCD 0x08 /* Delta DCD */ +#define UART_MSR_TERI 0x04 /* Trailing edge ring indicator */ +#define UART_MSR_DDSR 0x02 /* Delta DSR */ +#define UART_MSR_DCTS 0x01 /* Delta CTS */ +#define UART_MSR_ANY_DELTA 0x0F /* Any of the delta bits! */ + +#define UART_SCR 7 /* I/O: Scratch Register */ + +/* + * DLAB=1 + */ +#define UART_DLL 0 /* Out: Divisor Latch Low */ +#define UART_DLM 1 /* Out: Divisor Latch High */ + +/* + * LCR=0xBF (or DLAB=1 for 16C660) + */ +#define UART_EFR 2 /* I/O: Extended Features Register */ +#define UART_EFR_CTS 0x80 /* CTS flow control */ +#define UART_EFR_RTS 0x40 /* RTS flow control */ +#define UART_EFR_SCD 0x20 /* Special character detect */ +#define UART_EFR_ECB 0x10 /* Enhanced control bit */ +/* + * the low four bits control software flow control + */ + +/* + * LCR=0xBF, TI16C752, ST16650, ST16650A, ST16654 + */ +#define UART_XON1 4 /* I/O: Xon character 1 */ +#define UART_XON2 5 /* I/O: Xon character 2 */ +#define UART_XOFF1 6 /* I/O: Xoff character 1 */ +#define UART_XOFF2 7 /* I/O: Xoff character 2 */ + +/* + * EFR[4]=1 MCR[6]=1, TI16C752 + */ +#define UART_TI752_TCR 6 /* I/O: transmission control register */ +#define UART_TI752_TLR 7 /* I/O: trigger level register */ + +/* + * LCR=0xBF, XR16C85x + */ +#define UART_TRG 0 /* FCTR bit 7 selects Rx or Tx + * In: Fifo count + * Out: Fifo custom trigger levels */ +/* + * These are the definitions for the Programmable Trigger Register + */ +#define UART_TRG_1 0x01 +#define UART_TRG_4 0x04 +#define UART_TRG_8 0x08 +#define UART_TRG_16 0x10 +#define UART_TRG_32 0x20 +#define UART_TRG_64 0x40 +#define UART_TRG_96 0x60 +#define UART_TRG_120 0x78 +#define UART_TRG_128 0x80 + +#define UART_FCTR 1 /* Feature Control Register */ +#define UART_FCTR_RTS_NODELAY 0x00 /* RTS flow control delay */ +#define UART_FCTR_RTS_4DELAY 0x01 +#define UART_FCTR_RTS_6DELAY 0x02 +#define UART_FCTR_RTS_8DELAY 0x03 +#define UART_FCTR_IRDA 0x04 /* IrDa data encode select */ +#define UART_FCTR_TX_INT 0x08 /* Tx interrupt type select */ +#define UART_FCTR_TRGA 0x00 /* Tx/Rx 550 trigger table select */ +#define UART_FCTR_TRGB 0x10 /* Tx/Rx 650 trigger table select */ +#define UART_FCTR_TRGC 0x20 /* Tx/Rx 654 trigger table select */ +#define UART_FCTR_TRGD 0x30 /* Tx/Rx 850 programmable trigger select */ +#define UART_FCTR_SCR_SWAP 0x40 /* Scratch pad register swap */ +#define UART_FCTR_RX 0x00 /* Programmable trigger mode select */ +#define UART_FCTR_TX 0x80 /* Programmable trigger mode select */ + +/* + * LCR=0xBF, FCTR[6]=1 + */ +#define UART_EMSR 7 /* Extended Mode Select Register */ +#define UART_EMSR_FIFO_COUNT 0x01 /* Rx/Tx select */ +#define UART_EMSR_ALT_COUNT 0x02 /* Alternating count select */ + +/* + * The Intel XScale on-chip UARTs define these bits + */ +#define UART_IER_DMAE 0x80 /* DMA Requests Enable */ +#define UART_IER_UUE 0x40 /* UART Unit Enable */ +#define UART_IER_NRZE 0x20 /* NRZ coding Enable */ +#define UART_IER_RTOIE 0x10 /* Receiver Time Out Interrupt Enable */ + +#define UART_IIR_TOD 0x08 /* Character Timeout Indication Detected */ + +#define UART_FCR_PXAR1 0x00 /* receive FIFO threshold = 1 */ +#define UART_FCR_PXAR8 0x40 /* receive FIFO threshold = 8 */ +#define UART_FCR_PXAR16 0x80 /* receive FIFO threshold = 16 */ +#define UART_FCR_PXAR32 0xc0 /* receive FIFO threshold = 32 */ + + + + +/* + * These register definitions are for the 16C950 + */ +#define UART_ASR 0x01 /* Additional Status Register */ +#define UART_RFL 0x03 /* Receiver FIFO level */ +#define UART_TFL 0x04 /* Transmitter FIFO level */ +#define UART_ICR 0x05 /* Index Control Register */ + +/* The 16950 ICR registers */ +#define UART_ACR 0x00 /* Additional Control Register */ +#define UART_CPR 0x01 /* Clock Prescalar Register */ +#define UART_TCR 0x02 /* Times Clock Register */ +#define UART_CKS 0x03 /* Clock Select Register */ +#define UART_TTL 0x04 /* Transmitter Interrupt Trigger Level */ +#define UART_RTL 0x05 /* Receiver Interrupt Trigger Level */ +#define UART_FCL 0x06 /* Flow Control Level Lower */ +#define UART_FCH 0x07 /* Flow Control Level Higher */ +#define UART_ID1 0x08 /* ID #1 */ +#define UART_ID2 0x09 /* ID #2 */ +#define UART_ID3 0x0A /* ID #3 */ +#define UART_REV 0x0B /* Revision */ +#define UART_CSR 0x0C /* Channel Software Reset */ +#define UART_NMR 0x0D /* Nine-bit Mode Register */ +#define UART_CTR 0xFF + +/* + * The 16C950 Additional Control Register + */ +#define UART_ACR_RXDIS 0x01 /* Receiver disable */ +#define UART_ACR_TXDIS 0x02 /* Transmitter disable */ +#define UART_ACR_DSRFC 0x04 /* DSR Flow Control */ +#define UART_ACR_TLENB 0x20 /* 950 trigger levels enable */ +#define UART_ACR_ICRRD 0x40 /* ICR Read enable */ +#define UART_ACR_ASREN 0x80 /* Additional status enable */ + + + +/* + * These definitions are for the RSA-DV II/S card, from + * + * Kiyokazu SUTO + */ + +#define UART_RSA_BASE (-8) + +#define UART_RSA_MSR ((UART_RSA_BASE) + 0) /* I/O: Mode Select Register */ + +#define UART_RSA_MSR_SWAP (1 << 0) /* Swap low/high 8 bytes in I/O port addr */ +#define UART_RSA_MSR_FIFO (1 << 2) /* Enable the external FIFO */ +#define UART_RSA_MSR_FLOW (1 << 3) /* Enable the auto RTS/CTS flow control */ +#define UART_RSA_MSR_ITYP (1 << 4) /* Level (1) / Edge triger (0) */ + +#define UART_RSA_IER ((UART_RSA_BASE) + 1) /* I/O: Interrupt Enable Register */ + +#define UART_RSA_IER_Rx_FIFO_H (1 << 0) /* Enable Rx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_H (1 << 1) /* Enable Tx FIFO half full int. */ +#define UART_RSA_IER_Tx_FIFO_E (1 << 2) /* Enable Tx FIFO empty int. */ +#define UART_RSA_IER_Rx_TOUT (1 << 3) /* Enable char receive timeout int */ +#define UART_RSA_IER_TIMER (1 << 4) /* Enable timer interrupt */ + +#define UART_RSA_SRR ((UART_RSA_BASE) + 2) /* IN: Status Read Register */ + +#define UART_RSA_SRR_Tx_FIFO_NEMP (1 << 0) /* Tx FIFO is not empty (1) */ +#define UART_RSA_SRR_Tx_FIFO_NHFL (1 << 1) /* Tx FIFO is not half full (1) */ +#define UART_RSA_SRR_Tx_FIFO_NFUL (1 << 2) /* Tx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NEMP (1 << 3) /* Rx FIFO is not empty (1) */ +#define UART_RSA_SRR_Rx_FIFO_NHFL (1 << 4) /* Rx FIFO is not half full (1) */ +#define UART_RSA_SRR_Rx_FIFO_NFUL (1 << 5) /* Rx FIFO is not full (1) */ +#define UART_RSA_SRR_Rx_TOUT (1 << 6) /* Character reception timeout occurred (1) */ +#define UART_RSA_SRR_TIMER (1 << 7) /* Timer interrupt occurred */ + +#define UART_RSA_FRR ((UART_RSA_BASE) + 2) /* OUT: FIFO Reset Register */ + +#define UART_RSA_TIVSR ((UART_RSA_BASE) + 3) /* I/O: Timer Interval Value Set Register */ + +#define UART_RSA_TCR ((UART_RSA_BASE) + 4) /* OUT: Timer Control Register */ + +#define UART_RSA_TCR_SWITCH (1 << 0) /* Timer on */ + +/* + * The RSA DSV/II board has two fixed clock frequencies. One is the + * standard rate, and the other is 8 times faster. + */ +#define SERIAL_RSA_BAUD_BASE (921600) +#define SERIAL_RSA_BAUD_BASE_LO (SERIAL_RSA_BAUD_BASE / 8) + +/* + * Extra serial register definitions for the internal UARTs + * in TI OMAP processors. + */ +#define UART_OMAP_MDR1 0x08 /* Mode definition register */ +#define UART_OMAP_MDR2 0x09 /* Mode definition register 2 */ +#define UART_OMAP_SCR 0x10 /* Supplementary control register */ +#define UART_OMAP_SSR 0x11 /* Supplementary status register */ +#define UART_OMAP_EBLR 0x12 /* BOF length register */ +#define UART_OMAP_OSC_12M_SEL 0x13 /* OMAP1510 12MHz osc select */ +#define UART_OMAP_MVER 0x14 /* Module version register */ +#define UART_OMAP_SYSC 0x15 /* System configuration register */ +#define UART_OMAP_SYSS 0x16 /* System status register */ +#define UART_OMAP_WER 0x17 /* Wake-up enable register */ + +#endif /* _8250_SERIAL_H */ + diff --git a/ports/mips/Doxyfile b/ports/mips/Doxyfile new file mode 100644 index 0000000..8e621b7 --- /dev/null +++ b/ports/mips/Doxyfile @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = atomthreads + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen-mips + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ports/mips/Makefile b/ports/mips/Makefile new file mode 100644 index 0000000..04d340b --- /dev/null +++ b/ports/mips/Makefile @@ -0,0 +1,140 @@ +############ +# Settings # +############ + +# Build all test applications: +# make +# +# Program a test application using UISP (appname => test app e.g. sems1): +# make program app=appname + +# Location of build tools and atomthreads sources +KERNEL_DIR=../../kernel +TESTS_DIR=../../tests +CC=mips-linux-gnu-gcc +OBJCOPY=mips-linux-gnu-objcopy + +# Check if verbosity is ON for build process +VERBOSE_DEFAULT := 0 +CMD_PREFIX_DEFAULT := @ +ifdef VERBOSE + ifeq ("$(origin VERBOSE)", "command line") + VB := $(VERBOSE) + else + VB := $(VERBOSE_DEFAULT) + endif +else + VB := $(VERBOSE_DEFAULT) +endif +ifeq ($(VB), 1) + V := +else + V := $(CMD_PREFIX_DEFAULT) +endif + +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Directory for built objects +BUILD_DIR=build + +# Port/application object files +APP_OBJECTS = atomport.o tests-main.o 8250-serial.o printk.o string.o vsprintf.o io.o atomport-interrupts.o atomport-timer.o + +APP_ASM_OBJECTS = atomport-entry.o atomport-asm.o + +# Kernel object files +KERNEL_OBJECTS = atomkernel.o atomsem.o atommutex.o atomtimer.o atomqueue.o + +# Collection of built objects (excluding test applications) +ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) +BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) + +# Test object files (dealt with separately as only one per application build) +TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c))) + +# Target application filenames (.elf and .hex) for each test object +TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) +TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS)) + +# Search build/output directory for dependencies +vpath %.o ./$(BUILD_DIR) +vpath %.elf ./$(BUILD_DIR) +vpath %.hex ./$(BUILD_DIR) + +# GCC flags +CFLAGS= -g \ + -Wall \ + -Werror \ + -O \ + -fstrength-reduce \ + -fomit-frame-pointer \ + -finline-functions \ + -nostdinc \ + -fno-builtin \ + -fno-stack-protector + +# Enable stack-checking (disable if not required) +ifeq ($(STACK_CHECK),true) +CFLAGS += -DATOM_STACK_CHECKING +endif + +################# +# Build targets # +################# + +# All tests +all: $(BUILD_DIR) $(TEST_HEXS) Makefile + +# Make build/output directory +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +# Test HEX files (one application build for each test) +$(TEST_HEXS): %.hex: %.elf + $(if $(V), @echo " (HEX) $(subst $(build_dir)/,,$@)") + $(V)$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + +# Test ELF files (one application build for each test) +$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) --output $(BUILD_DIR)/$@ -Wl -T linker.ld + +# Kernel objects builder +$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Test objects builder +$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application C objects builder +$(APP_OBJECTS): %.o: ./%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application asm objects builder +$(APP_ASM_OBJECTS): %.o: ./%.s + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# .lst file builder +%.lst: %.c + $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + +# Clean +clean: + $(V)rm -f *.o *.elf *.map *.hex *.bin *.lst + rm -rf doxygen-kernel + rm -rf doxygen-mips + rm -rf build + +doxygen: + doxygen $(KERNEL_DIR)/Doxyfile + doxygen ./Doxyfile diff --git a/ports/mips/README b/ports/mips/README new file mode 100644 index 0000000..5f778c8 --- /dev/null +++ b/ports/mips/README @@ -0,0 +1,3 @@ + * Required Ubuntu packages: qemu, qemu-kvm-extras + * Compiler: CodeSourcery + * Run test: qemu-system-mips -M mips -m 128 -kernel build/kern1.elf -nographic diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h new file mode 100644 index 0000000..39b9bb6 --- /dev/null +++ b/ports/mips/atomport-asm-macros.h @@ -0,0 +1,283 @@ +#ifndef __ATOMPORT_ASM_MACROS_H_ +#define __ATOMPORT_ASM_MACROS_H_ + +#include "regs.h" + +#ifdef __ASSEMBLY__ /* to be called only from assembly */ + +#define LEAF(fn) \ + .globl fn; \ + .ent fn; \ +fn: + +#define END(fn) \ + .size fn,.-fn; \ + .end fn + +#define tlbp_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbp_read_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define tlbw_write_hazard \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; \ + nop; + +#define enable_global_interrupts ei $0 +#define disable_global_interrupts di $0 + +#define EXCEPTION_VECTOR(_name, _offset, _where)\ + . = _offset; \ + .set noreorder; \ +_name: \ + b _where; \ + nop; + +#define SAVE_REG(reg, treg) \ + sw reg, ((reg ## _IDX) * 4)(treg) + +#define LOAD_REG(reg, treg) \ + lw reg, ((reg ## _IDX) * 4)(treg) + +#define SAVE_INT_CONTEXT \ + addiu sp, sp, -((NUM_REGISTERS + 1)* 4); \ + mfc0 k1, CP0_EPC; \ + SAVE_REG(t0,sp); \ + SAVE_REG(t1,sp); \ + SAVE_REG(t2,sp); \ + SAVE_REG(t3,sp); \ + SAVE_REG(t4,sp); \ + SAVE_REG(t5,sp); \ + SAVE_REG(t6,sp); \ + SAVE_REG(t7,sp); \ + SAVE_REG(t8,sp); \ + SAVE_REG(t9,sp); \ + SAVE_REG(v0,sp); \ + SAVE_REG(v1,sp); \ + SAVE_REG(a0,sp); \ + SAVE_REG(a1,sp); \ + SAVE_REG(a2,sp); \ + SAVE_REG(a3,sp); \ + SAVE_REG(s0,sp); \ + SAVE_REG(s1,sp); \ + SAVE_REG(s2,sp); \ + SAVE_REG(s3,sp); \ + SAVE_REG(s4,sp); \ + SAVE_REG(s5,sp); \ + SAVE_REG(s6,sp); \ + SAVE_REG(s7,sp); \ + SAVE_REG(gp,sp); \ + SAVE_REG(s8,sp); \ + SAVE_REG(ra,sp); \ + sw k0, (sp_IDX * 4)(sp); \ + sw k1, (NUM_REGISTERS * 4)(sp); + +#define RESTORE_INT_CONTEXT \ + lw k1, (NUM_REGISTERS * 4)(sp); \ + mtc0 k1, CP0_EPC; \ + LOAD_REG(s0,sp); \ + LOAD_REG(s1,sp); \ + LOAD_REG(s2,sp); \ + LOAD_REG(s3,sp); \ + LOAD_REG(s4,sp); \ + LOAD_REG(s5,sp); \ + LOAD_REG(s6,sp); \ + LOAD_REG(s7,sp); \ + LOAD_REG(v0,sp); \ + LOAD_REG(v1,sp); \ + LOAD_REG(a0,sp); \ + LOAD_REG(a1,sp); \ + LOAD_REG(a2,sp); \ + LOAD_REG(a3,sp); \ + LOAD_REG(t0,sp); \ + LOAD_REG(t1,sp); \ + LOAD_REG(t2,sp); \ + LOAD_REG(t3,sp); \ + LOAD_REG(t4,sp); \ + LOAD_REG(t5,sp); \ + LOAD_REG(t6,sp); \ + LOAD_REG(t7,sp); \ + LOAD_REG(t8,sp); \ + LOAD_REG(t9,sp); \ + LOAD_REG(gp,sp); \ + LOAD_REG(ra,sp); \ + LOAD_REG(s8,sp); \ + lw sp, (sp_IDX * 4)(sp); + +#endif /* __ASSEMBLY__ */ + +#define num_to_string(s) to_string(s) +#define to_string(s) #s + +#define IASM_SAVE_REG(reg, here) \ + "sw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + +#define IASM_LOAD_REG(reg, here) \ + "lw " to_string(reg) " , " num_to_string(reg ## _IDX) \ + " * 4(" num_to_string(here)" )\n\t" + + +/* + * Macros to be used with C code. + */ +#define __read_32bit_c0_register(source, sel) \ +({ int __res; \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mfc0\t%0, " #source "\n\t" \ + : "=r" (__res)); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mfc0\t%0, " #source ", " #sel "\n\t" \ + ".set\tmips0\n\t" \ + : "=r" (__res)); \ + __res; \ +}) + +#define __write_32bit_c0_register(register, sel, value) \ +do { \ + if (sel == 0) \ + __asm__ __volatile__( \ + "mtc0\t%z0, " #register "\n\t" \ + : : "Jr" ((unsigned int)(value))); \ + else \ + __asm__ __volatile__( \ + ".set\tmips32\n\t" \ + "mtc0\t%z0, " #register ", " #sel "\n\t" \ + ".set\tmips0" \ + : : "Jr" ((unsigned int)(value))); \ +} while (0) + +#define __read_ulong_c0_register(reg, sel) \ + (unsigned long) __read_32bit_c0_register(reg, sel) + +#define __write_ulong_c0_register(reg, sel, val) \ +do { \ + __write_32bit_c0_register(reg, sel, val); \ +} while (0) + +#define read_c0_index() __read_32bit_c0_register($0, 0) +#define write_c0_index(val) __write_32bit_c0_register($0, 0, val) + +#define read_c0_entrylo0() __read_ulong_c0_register($2, 0) +#define write_c0_entrylo0(val) __write_ulong_c0_register($2, 0, val) + +#define read_c0_entrylo1() __read_ulong_c0_register($3, 0) +#define write_c0_entrylo1(val) __write_ulong_c0_register($3, 0, val) + +#define read_c0_conf() __read_32bit_c0_register($3, 0) +#define write_c0_conf(val) __write_32bit_c0_register($3, 0, val) + +#define read_c0_context() __read_ulong_c0_register($4, 0) +#define write_c0_context(val) __write_ulong_c0_register($4, 0, val) + +#define read_c0_userlocal() __read_ulong_c0_register($4, 2) +#define write_c0_userlocal(val) __write_ulong_c0_register($4, 2, val) + +#define read_c0_pagemask() __read_32bit_c0_register($5, 0) +#define write_c0_pagemask(val) __write_32bit_c0_register($5, 0, val) + +#define read_c0_wired() __read_32bit_c0_register($6, 0) +#define write_c0_wired(val) __write_32bit_c0_register($6, 0, val) + +#define read_c0_info() __read_32bit_c0_register($7, 0) + +#define read_c0_badvaddr() __read_ulong_c0_register($8, 0) +#define write_c0_badvaddr(val) __write_ulong_c0_register($8, 0, val) + +#define read_c0_count() __read_32bit_c0_register($9, 0) +#define write_c0_count(val) __write_32bit_c0_register($9, 0, val) + +#define read_c0_entryhi() __read_ulong_c0_register($10, 0) +#define write_c0_entryhi(val) __write_ulong_c0_register($10, 0, val) + +#define read_c0_compare() __read_32bit_c0_register($11, 0) +#define write_c0_compare(val) __write_32bit_c0_register($11, 0, val) + +#define read_c0_status() __read_32bit_c0_register($12, 0) +#define write_c0_status(val) __write_32bit_c0_register($12, 0, val) + +#define read_c0_cause() __read_32bit_c0_register($13, 0) +#define write_c0_cause(val) __write_32bit_c0_register($13, 0, val) + +#define read_c0_epc() __read_ulong_c0_register($14, 0) +#define write_c0_epc(val) __write_ulong_c0_register($14, 0, val) + +#define read_c0_prid() __read_32bit_c0_register($15, 0) + +#define read_c0_config() __read_32bit_c0_register($16, 0) +#define read_c0_config1() __read_32bit_c0_register($16, 1) +#define read_c0_config2() __read_32bit_c0_register($16, 2) +#define write_c0_config(val) __write_32bit_c0_register($16, 0, val) +#define write_c0_config1(val) __write_32bit_c0_register($16, 1, val) +#define write_c0_config2(val) __write_32bit_c0_register($16, 2, val) + +#define read_c0_xcontext() __read_ulong_c0_register($20, 0) +#define write_c0_xcontext(val) __write_ulong_c0_register($20, 0, val) + +#define read_c0_intcontrol() __read_32bit_c0_ctrl_register($20) +#define write_c0_intcontrol(val) __write_32bit_c0_ctrl_register($20, val) + +#define read_c0_framemask() __read_32bit_c0_register($21, 0) +#define write_c0_framemask(val) __write_32bit_c0_register($21, 0, val) + +/* + * MIPS32 / MIPS64 performance counters + */ +#define read_c0_cacheerr() __read_32bit_c0_register($27, 0) + +#define read_c0_taglo() __read_32bit_c0_register($28, 0) +#define write_c0_taglo(val) __write_32bit_c0_register($28, 0, val) + +#define read_c0_dtaglo() __read_32bit_c0_register($28, 2) +#define write_c0_dtaglo(val) __write_32bit_c0_register($28, 2, val) + +#define read_c0_taghi() __read_32bit_c0_register($29, 0) +#define write_c0_taghi(val) __write_32bit_c0_register($29, 0, val) + +#define read_c0_errorepc() __read_ulong_c0_register($30, 0) +#define write_c0_errorepc(val) __write_ulong_c0_register($30, 0, val) + +/* MIPSR2 */ +#define read_c0_hwrena() __read_32bit_c0_register($7, 0) +#define write_c0_hwrena(val) __write_32bit_c0_register($7, 0, val) + +#define read_c0_intctl() __read_32bit_c0_register($12, 1) +#define write_c0_intctl(val) __write_32bit_c0_register($12, 1, val) + +#define read_c0_srsctl() __read_32bit_c0_register($12, 2) +#define write_c0_srsctl(val) __write_32bit_c0_register($12, 2, val) + +#define read_c0_srsmap() __read_32bit_c0_register($12, 3) +#define write_c0_srsmap(val) __write_32bit_c0_register($12, 3, val) + +#define read_c0_ebase() __read_32bit_c0_register($15, 1) +#define write_c0_ebase(val) __write_32bit_c0_register($15, 1, val) + +#endif /* __ATOMPORT_ASM_MACROS_H_ */ diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s new file mode 100644 index 0000000..2b64746 --- /dev/null +++ b/ports/mips/atomport-asm.s @@ -0,0 +1,186 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + +.section .text + +.extern atomCurrentContext +.extern at_preempt_count + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +.globl archContextSwitch +archContextSwitch: + /* + * Check if we are being called in interrupt + * context. If yes, we need to restore complete + * context and return directly from here. + */ + move k0, ra + bal atomCurrentContext + nop + beq v0, zero, __in_int_context + nop + + move ra, k0 + move v0, a0 /* return old tcb when we return from here */ + lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ + sw s0, (s0_IDX * 4)(k0) + sw s1, (s1_IDX * 4)(k0) + sw s2, (s2_IDX * 4)(k0) + sw s3, (s3_IDX * 4)(k0) + sw s4, (s4_IDX * 4)(k0) + sw s5, (s5_IDX * 4)(k0) + sw s6, (s6_IDX * 4)(k0) + sw s7, (s7_IDX * 4)(k0) + sw s8, (s8_IDX * 4)(k0) + sw sp, (sp_IDX * 4)(k0) + sw gp, (gp_IDX * 4)(k0) + sw ra, (ra_IDX * 4)(k0) + /* + * We are saving registers in non-interrupt context because + * a thread probably is trying to yield CPU. Storing zero + * in EPC offset differentiates this. When restoring the + * context, if EPC offset has zero we will restore only + * the partial context. Rest will be done by GCC while + * unwinding the call. + */ + sw zero, (cp0_epc_IDX * 4)(k0) + + lw k1, 0(a1) + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw ra, (ra_IDX * 4)(k1) + + jr ra + nop + +__in_int_context: + move ra, k0 + /* + * In interrupt context, the interrupt handler + * saves the context for us. Its very well there + * and we don't need to do it again. + * + * We will figure out of the task that we are + * switching in was saved in interrupt context + * or otherwise. + */ + lw k0, (cp0_epc_IDX * 4)(k1) + bnez k0, __unwind_int_context + nop + + /* + * Unwinding a task switched in non-interrupt context. + * So, restore only the partials. But since we are in + * interrupt mode, we will put ra in epc and do a eret + * so that we get out of interrupt mode and switch to + * the new task. + */ +__unwind_non_int_context: + lw s0, (s0_IDX * 4)(k1) + lw s1, (s1_IDX * 4)(k1) + lw s2, (s2_IDX * 4)(k1) + lw s3, (s3_IDX * 4)(k1) + lw s4, (s4_IDX * 4)(k1) + lw s5, (s5_IDX * 4)(k1) + lw s6, (s6_IDX * 4)(k1) + lw s7, (s7_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw gp, (gp_IDX * 4)(k1) + lw ra, (ra_IDX * 4)(k1) + mtc0 ra, CP0_EPC + nop + nop + nop + j __ret_from_switch + nop + +__unwind_int_context: + move sp, k1 + RESTORE_INT_CONTEXT + +__ret_from_switch: + la k0, at_preempt_count + lw k1, (k0) + addi k1, k1, -1 + sw k1, (k0) + bnez k1, __return_from_int + nop + enable_global_interrupts + ehb +__return_from_int: + eret + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +.globl archFirstThreadRestore +archFirstThreadRestore: + move k0, a0 /* save the copy of tcb pointer in k0 */ + lw k1, 0(k0) /* Assume that sp_save_ptr is always at base of ATOM_TCB */ + lw a0, (a0_IDX * 4)(k1) + lw sp, (sp_IDX * 4)(k1) + lw s8, (s8_IDX * 4)(k1) + lw k0, (ra_IDX * 4)(k1) + mtc0 k0, CP0_EPC + nop + nop + nop + enable_global_interrupts + eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s new file mode 100644 index 0000000..35b5735 --- /dev/null +++ b/ports/mips/atomport-entry.s @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atomport-asm-macros.h" + +.extern _stack_start +.section .start.text,"ax",@progbits + +EXCEPTION_VECTOR(_tlbmiss, 0x00, _handle_tlbmiss) +EXCEPTION_VECTOR(_cache_error, 0x100, _handle_cache_error) +EXCEPTION_VECTOR(_general_exception, 0x180, _handle_general_exception) +/* FIXME: We don't need this when in EIC mode. */ +EXCEPTION_VECTOR(_interrupts, 0x200, _handle_interrupt) + +LEAF(_start) + mtc0 zero, CP0_CONTEXT + nop + nop + nop + + /* globally disable interrupts until we are prepared. */ + disable_global_interrupts + + /* clear CPU timer counters. We don't want surprises. */ + mtc0 zero, CP0_COMPARE + mtc0 zero, CP0_COUNT + + li a0, 0xC0000000 /* FIXME: Remove these two hard codings */ + li a1, 0x14000000 + bal create_tlb_entry + move zero, a2 + + la sp, _stack_start /* setup the stack (bss segment) */ + la t0, main + j t0 /* Call the C- code now */ + nop + +1: b 1b /* we should not come here whatsoever */ +END(_start) + +LEAF(_handle_tlbmiss) +#if 0 + disable_global_interrupts + move k0, sp + SAVE_INT_CONTEXT(_int_stack) + move a0, sp + bal vmm_cpu_handle_pagefault + nop + enable_global_interrupts + eret +#else + b _handle_tlbmiss + nop +#endif +END(_handle_tlbmiss) + +.extern handle_mips_systick +.extern _int_stack +LEAF(_handle_interrupt) + disable_global_interrupts + mfc0 k0, CP0_CAUSE + lui k1, 0x4000 + and k0, k1, k0 + beq k0, zero, 1f + nop + + move k0, ra + move k1, v0 + bal atomCurrentContext + nop + beq v0, zero, 2f /* v0 should be current context */ + nop + + move ra, k0 + lw k0, 0(v0) + move v0, k1 + move k1, k0 + /* + * Note that we aren't loading any new SP. Context + * will be save on the interrupted threads' stack. + */ + move k0, sp + move sp, k1 + SAVE_INT_CONTEXT + bal handle_mips_systick + nop + RESTORE_INT_CONTEXT +1: + enable_global_interrupts + eret + +2: b 2b +END(_handle_interrupt) + +LEAF(_handle_cache_error) + b _handle_cache_error + nop +END(_handle_cache_error) + +LEAF(_handle_general_exception) + b _handle_general_exception + nop +END(_handle_general_exception) + +/** + * a0 -> Contains virtual address. + * a1 -> Contains physical address. + * a2 -> TLB index: If -1 select automatically. + */ +.globl create_tlb_entry +LEAF(create_tlb_entry) + mtc0 a2, CP0_INDEX /* load the tlb index to be programmed. */ + srl a0, a0, 12 /* get the VPN */ + sll a0, a0, 12 + nop + mtc0 a0, CP0_ENTRYHI /* load VPN in entry hi */ + addi t0, a1, 0x1000 /* next PFN for entry lo1 in T0 */ + srl a1, a1, 12 /* get the PFN */ + sll a1, a1, 6 /* get the PFN */ + srl t0, t0, 12 + sll t0, t0, 6 + ori a1, a1, 0x7 /* mark the page writable, global and valid */ + mtc0 a1, CP0_ENTRYLO0 + ori t0, t0, 0x7 /* mark the next physical page writable, global and valid */ + nop + nop + mtc0 t0, CP0_ENTRYLO1 + nop + nop + nop + tlbwi + ehb + j ra + nop +END(create_tlb_entry) diff --git a/ports/mips/atomport-interrupts.c b/ports/mips/atomport-interrupts.c new file mode 100644 index 0000000..e0065da --- /dev/null +++ b/ports/mips/atomport-interrupts.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +void mips_setup_interrupts() +{ + uint32_t ebase = read_c0_ebase(); + ebase &= ~0x3FFF000UL; + write_c0_ebase(ebase); + + uint32_t sr = read_c0_status(); + sr &= ~(0x01UL << 22); + sr &= ~(0x3UL << 1); + write_c0_status(sr); + + uint32_t cause = read_c0_status(); + cause |= 0x01UL << 23; + write_c0_cause(cause); +} + +void mips_enable_global_interrupts(void) +{ + __asm__ __volatile__ ("ei $0\t\n"); +} + +void mips_disable_global_interrupts(void) +{ + __asm__ __volatile__("di $0\t\n"); +} diff --git a/ports/mips/atomport-interrupts.h b/ports/mips/atomport-interrupts.h new file mode 100644 index 0000000..41200de --- /dev/null +++ b/ports/mips/atomport-interrupts.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_INTERRUPTS_H +#define __ATOMPORT_INTERRUPTS_H + +void mips_setup_interrupts(); +void mips_enable_global_interrupts(void); +void mips_disable_global_interrupts(void); +void handle_mips_systick(void); + +#endif /* __ATOMPORT_INTERRUPTS_H */ diff --git a/ports/mips/atomport-private.h b/ports/mips/atomport-private.h new file mode 100644 index 0000000..499a5a9 --- /dev/null +++ b/ports/mips/atomport-private.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_PRIVATE_H_ +#define __ATOMPORT_PRIVATE_H_ + +/* Function prototypes */ +void mips_cpu_timer_enable(void); + +#endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h new file mode 100644 index 0000000..4b44513 --- /dev/null +++ b/ports/mips/atomport-tests.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H +#define __ATOM_PORT_TESTS_H + +/* Include Atomthreads kernel API */ +#include "atom.h" + +/* Prerequisite include for ATOMLOG() macro (via printf) */ +#include "printk.h" + +/* Logger macro for viewing test results */ +/* FIXME: Add uart out routine once uart is supported */ +#define ATOMLOG printk +#define _STR + +/* Default thread stack size (in bytes) */ +#define TEST_THREAD_STACK_SIZE 8192 + +/* Uncomment to enable logging of stack usage to UART */ +/* #define TESTS_LOG_STACK_USAGE */ + +#endif /* __ATOM_PORT_TESTS_H */ + diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c new file mode 100644 index 0000000..3997a29 --- /dev/null +++ b/ports/mips/atomport-timer.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +/** CPU frequency in MHz */ +#define CPU_FREQ_MHZ 100 + +/** Number of counter counter should increase to get required ticks */ +#define COUNTER_TICK_COUNT ((1000000 * SYSTEM_TICKS_PER_SEC) / CPU_FREQ_MHZ) + +unsigned long long jiffies; + +void mips_cpu_timer_enable(void) +{ + uint32_t sr = read_c0_status(); + sr |= ((0x1UL << 7) << 8); + write_c0_status(sr); + + uint32_t cause = read_c0_cause(); + cause &= ~(0x1UL << 27); + write_c0_cause(cause); + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} + +void handle_mips_systick(void) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); +} diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c new file mode 100644 index 0000000..0af7f71 --- /dev/null +++ b/ports/mips/atomport.c @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include "regs.h" +#include + + +/* Used for managing nesting of atomport.h critical sections */ +uint32_t at_preempt_count = 0; + +/** + * This function initialises each thread's stack during creation, before the + * thread is first run. New threads are scheduled in using the same + * context-switch function used for threads which were previously scheduled + * out, therefore this function should set up a stack context which looks + * much like a thread which has been scheduled out and had its context saved. + * We fill part of the stack with those registers which are involved in the + * context switch, including appropriate stack or register contents to cause + * the thread to branch to its entry point function when it is scheduled in. + * + * Interrupts should also be enabled whenever a thread is restored, hence + * ports may wish to explicitly include the interrupt-enable register here + * which will be restored when the thread is scheduled in. Other methods + * can be used to enable interrupts, however, without explicitly storing + * it in the thread's context. + */ +void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, + void (*entry_point)(UINT32), + UINT32 entry_param) +{ + +#define STORE_VAL(base, reg, val) \ + *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val + + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * (NUM_REGISTERS + 1))); + + tcb_ptr->sp_save_ptr = (void *)stack_start; + + STORE_VAL(stack_start, sp, stack_start); + STORE_VAL(stack_start, s8, stack_start); + STORE_VAL(stack_start, s1, 0); + STORE_VAL(stack_start, s2, 0); + STORE_VAL(stack_start, s3, 0); + STORE_VAL(stack_start, s4, 0); + STORE_VAL(stack_start, s5, 0); + STORE_VAL(stack_start, s6, 0); + STORE_VAL(stack_start, s7, 0); + STORE_VAL(stack_start, cp0_epc, entry_point); + STORE_VAL(stack_start, ra, entry_point); + STORE_VAL(stack_start, a0, entry_param); +} + diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h new file mode 100644 index 0000000..b7a6832 --- /dev/null +++ b/ports/mips/atomport.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H +#define __ATOM_PORT_H + + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +/** + * Definition of NULL. stddef.h not available on this platform. + */ +#define NULL ((void *)(0)) + +/* Size of each stack entry / stack alignment size (32 bits on MIPS) */ +#define STACK_ALIGN_SIZE sizeof(uint32_t) + +/** + * Architecture-specific types. + * Provide stdint.h style types. + */ +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned long +#define uint64_t unsigned long long +#define int8_t char +#define int16_t short +#define int32_t long +#define int64_t long long +#define size_t unsigned long +#define POINTER void * +#define UINT32 uint32_t + + +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ +extern uint32_t at_preempt_count; +#define CRITICAL_STORE uint32_t status_reg +#define CRITICAL_START() \ + do { \ + __asm__ __volatile__("di %0\t\n" \ + "ehb\t\n" \ + :"=r"(status_reg)); \ + at_preempt_count++; \ + }while(0); + +#define CRITICAL_END() \ + do { \ + at_preempt_count--; \ + \ + if (at_preempt_count == 0) { \ + if (atomCurrentContext()) { \ + __asm__ __volatile__("ei %0\t\n" \ + "ehb\t\n" \ + ::"r"(status_reg));\ + } \ + } \ + \ + }while(0); + +/* Uncomment to enable stack-checking */ +/* #define ATOM_STACK_CHECKING */ + + +#endif /* __ATOM_PORT_H */ diff --git a/ports/mips/io.c b/ports/mips/io.c new file mode 100644 index 0000000..90b714c --- /dev/null +++ b/ports/mips/io.c @@ -0,0 +1,44 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 + +uint8_t ioreadb (void *addr) +{ + uint8_t rv; + rv = *((volatile uint8_t *)addr); + return rv; +} + +void iowriteb (void *addr, uint8_t data) +{ + *(volatile uint8_t *)addr = data; +} + diff --git a/ports/mips/linker.ld b/ports/mips/linker.ld new file mode 100755 index 0000000..98d6df6 --- /dev/null +++ b/ports/mips/linker.ld @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-tradbigmips") +OUTPUT_ARCH("mips") +ENTRY(_start) + +SECTIONS +{ + . = 0x80000000; + .text : + { + *(.start.text) + *(.text) + . = ALIGN(4); + _etext = .; + } + + .data : + { + *(.data) + . = ALIGN(4); + _edata = .; + } + + .bss : + { + *(.bss) + . = ALIGN(4); + _ebss = .; + } + + .rodata : + { + *(.rodata .rodata.*) + . = ALIGN(4); + _erodata = .; + } + + PROVIDE(_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_stack_start = .); + PROVIDE(_int_stack_end = .); + . = . + 8192; + . = ALIGN(4); + PROVIDE(_int_stack = .); +} diff --git a/ports/mips/printk.c b/ports/mips/printk.c new file mode 100644 index 0000000..cf736ce --- /dev/null +++ b/ports/mips/printk.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include "system.h" +#include "atomport.h" +#include "printk.h" + +static int8_t buf[2048]; + +/* Uses the above routine to output a string... */ +void puts(const uint8_t *text) +{ + int32_t i; + + for (i = 0; i < strlen((const int8_t *)text); i++) { + putch(text[i]); + } +} + +void printk(const char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = vsprintf(buf, (const int8_t *)format, args); + va_end(args); + + puts((const uint8_t *)buf); +} + diff --git a/ports/mips/printk.h b/ports/mips/printk.h new file mode 100644 index 0000000..bd1b192 --- /dev/null +++ b/ports/mips/printk.h @@ -0,0 +1,42 @@ +/* + * This file is part of Freax kernel. + * + * Copyright (c) Himanshu Chauhan 2009-10. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H +#define _PRINTK_H + +#include "atomport.h" + +extern void putch (uint8_t ch); +extern void puts (const uint8_t *text); +extern void printk (const char*format, ...); + +#endif diff --git a/ports/mips/regs.h b/ports/mips/regs.h new file mode 100644 index 0000000..ecf77d5 --- /dev/null +++ b/ports/mips/regs.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_REGS_H_ +#define __ATOMPORT_REGS_H_ + + +#define zero $0 +#define at $1 +#define v0 $2 +#define v1 $3 +#define a0 $4 +#define a1 $5 +#define a2 $6 +#define a3 $7 +#define t0 $8 +#define t1 $9 +#define t2 $10 +#define t3 $11 +#define t4 $12 +#define t5 $13 +#define t6 $14 +#define t7 $15 +#define t8 $24 +#define t9 $25 +#define s0 $16 +#define s1 $17 +#define s2 $18 +#define s3 $19 +#define s4 $20 +#define s5 $21 +#define s6 $22 +#define s7 $23 +#define k0 $26 +#define k1 $27 +#define gp $28 +#define sp $29 +#define s8 $30 +#define fp $30 +#define ra $31 + +#define NUM_REGISTERS 32 +#define WORD_SIZE 4 + +#define v0_IDX 0 +#define v1_IDX 1 +#define a0_IDX 2 +#define a1_IDX 3 +#define a2_IDX 4 +#define a3_IDX 5 +#define t0_IDX 6 +#define t1_IDX 7 +#define t2_IDX 8 +#define t3_IDX 9 +#define t4_IDX 10 +#define t5_IDX 11 +#define t6_IDX 12 +#define t7_IDX 13 +#define s0_IDX 14 +#define s1_IDX 15 +#define s2_IDX 16 +#define s3_IDX 17 +#define s4_IDX 18 +#define s5_IDX 19 +#define s6_IDX 20 +#define s7_IDX 21 +#define t8_IDX 22 +#define t9_IDX 23 +#define sp_IDX 24 +#define gp_IDX 25 +#define s8_IDX 26 +#define ra_IDX 27 +#define k0_IDX 28 +#define k1_IDX 29 +#define at_IDX 30 +#define zero_IDX 31 +#define cp0_epc_IDX 32 + +#define CP0_INDEX $0 +#define CP0_RANDOM $1 +#define CP0_ENTRYLO0 $2 +#define CP0_ENTRYLO1 $3 +#define CP0_CONTEXT $4 +#define CP0_PAGEMASK $5 +#define CP0_WIRED $6 +#define CP0_HWRENA $7 +#define CP0_BADVADDR $8 +#define CP0_COUNT $9 +#define CP0_ENTRYHI $10 +#define CP0_COMPARE $11 +#define CP0_STATUS $12 +#define CP0_INTCTL $12,1 +#define CP0_SRSCTL $12,2 +#define CP0_SRSMAP $12,3 +#define CP0_CAUSE $13 +#define CP0_EPC $14 +#define CP0_PRID $15 +#define CP0_EBASE $15,1 +#define CP0_CONFIG $16 +#define CP0_CONFIG1 $16,1 +#define CP0_CONFIG2 $16,2 +#define CP0_CONFIG3 $16,3 +#define CP0_LLADDR $17 +#define CP0_WATCHLO $18 +#define CP0_WATCHHI $19 +#define CP0_DEBUG $23 +#define CP0_DEPC $24 +#define CP0_PERFCTL $25,0 +#define CP0_PERFCNT $25,1 +#define CP0_ECC $26 +#define CP0_CACHEERR $27 +#define CP0_TAGLO $28 +#define CP0_DATALO $28,1 +#define CP0_TAGHI $29 +#define CP0_DATAHI $29,1 +#define CP0_ERRORPC $30 + +#endif /* __ATOMPORT_REGS_H_ */ diff --git a/ports/mips/stdarg.h b/ports/mips/stdarg.h new file mode 100755 index 0000000..fd79ec0 --- /dev/null +++ b/ports/mips/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/ports/mips/string.c b/ports/mips/string.c new file mode 100644 index 0000000..b99b529 --- /dev/null +++ b/ports/mips/string.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +void *memcpy(void *dest, const void *src, size_t count) +{ + const int8_t *sp = (const int8_t *)src; + int8_t *dp = (int8_t *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, int8_t val, size_t count) +{ + int8_t *temp = (int8_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) +{ + uint16_t *temp = (uint16_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +size_t strlen(const int8_t *str) +{ + size_t retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} diff --git a/ports/mips/string.h b/ports/mips/string.h new file mode 100644 index 0000000..bbccc25 --- /dev/null +++ b/ports/mips/string.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H +#define __STRING_H + +#include + +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *dest, int8_t val, size_t count); +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); +size_t strlen(const int8_t *str); + +#endif /* __STRING_H */ + diff --git a/ports/mips/system.h b/ports/mips/system.h new file mode 100644 index 0000000..b8c25ad --- /dev/null +++ b/ports/mips/system.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H +#define _SYSTEM_H + +#include +#include + +extern const uint8_t *kernel_name; +extern const uint8_t *kernel_version; +extern const uint8_t *kernel_bdate; +extern const uint8_t *kernel_btime; + +extern void *memcpy (void *dest, const void *src, size_t count); +extern void *memset (void *dest, int8_t val, size_t count); +extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); +extern size_t strlen (const int8_t *str); +extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); +extern void init_console (void); +extern int32_t arch_init (void); +extern uint8_t ioreadb (void *addr); +extern void iowriteb (void *addr, uint8_t data); + +#endif /* _SYSTEM_H */ diff --git a/ports/mips/tests-main.c b/ports/mips/tests-main.c new file mode 100644 index 0000000..6e3e37b --- /dev/null +++ b/ports/mips/tests-main.c @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2011, Himanshu Chauhan. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 "atom.h" +#include "atomport-private.h" +#include "atomport.h" +#include "atomtests.h" +#include "atomtimer.h" +#include "system.h" +#include "atomport-interrupts.h" + + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + * + * In this case, the idle stack is allocated on the BSS via the + * idle_thread_stack[] byte array. + */ +#define IDLE_STACK_SIZE_BYTES 8192 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop + * flashing a LED. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + * + * With all OS tests implemented to date on the AVR, the Main thread + * stack has not exceeded 198 bytes. To allow all tests to run we set + * a minimum main thread stack size of 204 bytes. This may increase in + * future as the codebase changes but for the time being is enough to + * cope with all of the automated tests. + */ +#define MAIN_STACK_SIZE_BYTES 8192 + + +/* + * Startup code stack + * + * Some stack space is required at initial startup for running the main() + * routine. This stack space is only temporarily required at first bootup + * and is no longer required as soon as the OS is started. By default + * GCC sets this to the top of RAM (RAMEND) and it grows down from there. + * Because we only need this temporarily, though, it would be wasteful to + * set aside a region at the top of RAM which is not used during runtime. + * + * What we do here is to reuse part of the idle thread's stack during + * initial startup. As soon as we enter the main() routine we move the + * stack pointer to half-way down the idle thread's stack. This is used + * temporarily while calls are made to atomOSInit(), atomThreadCreate() + * and atomOSStart(). Once the OS is started this stack area is no + * longer required, and can be used for its original purpose (for the + * idle thread's stack). + * + * This does mean, however, that we cannot monitor the stack usage of the + * idle thread. Stack usage is monitored by prefilling the stack with a + * known value, and we are obliterating some of that prefilled area by + * using it as our startup stack, so we cannot use the stack-checking API + * to get a true picture of idle thread stack usage. If you wish to + * monitor idle thread stack usage for your applications then you are + * free to use a different region for the startup stack (e.g. set aside + * an area permanently, or place it somewhere you know you can reuse + * later in the application). For the time being, this method gives us a + * simple way of reducing the memory consumption without having to add + * any special AVR-specific considerations to the automated test + * applications. + * + * This optimisation was required to allow some of the larger automated + * test modules to run on devices with 1KB of RAM. You should avoid doing + * this if you can afford to set aside 64 bytes or so, or if you are + * writing your own applications in which you have further control over + * where data is located. + */ + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + + +/** + * \b main + * + * Program entry point. + * + * Sets up the AVR hardware resources (system tick timer interrupt) necessary + * for the OS to be started. Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /* Initialise the OS before creating our threads */ + status = atomOSInit(&idle_thread_stack[0], IDLE_STACK_SIZE_BYTES, TRUE); + if (status == ATOM_OK) + { + /* Enable the system tick timer */ + mips_cpu_timer_enable(); + mips_setup_interrupts(); + + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, + TRUE); + if (status == ATOM_OK) + { + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1) + ; + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + uint32_t test_status; + + /* Initialise UART */ + init_console(); + + /* Put a message out on the UART */ + printk ("Go\n"); + + /* Start test. All tests use the same start API. */ + test_status = test_start(); + + /* Check main thread stack usage (if enabled) */ +#ifdef ATOM_STACK_CHECKING + if (test_status == 0) + { + uint32_t used_bytes, free_bytes; + + /* Check idle thread stack usage */ + if (atomThreadStackCheck (&main_tcb, &used_bytes, &free_bytes) == ATOM_OK) + { + /* Check the thread did not use up to the end of stack */ + if (free_bytes == 0) + { + printk ("Main stack overflow\n"); + test_status++; + } + + /* Log the stack usage */ +#ifdef TESTS_LOG_STACK_USAGE + printk ("MainUse:%d\n", used_bytes); +#endif + } + + } +#endif + + /* Log final status */ + if (test_status == 0) + { + printk ("Pass\n"); + } + else + { + printk ("Fail(%d)\n", test_status); + } + + /* Test finished, loop forever */ + while (1) + { + /* Sleep */ + atomTimerDelay (1); + } + +} diff --git a/ports/mips/vsprintf.c b/ports/mips/vsprintf.c new file mode 100644 index 0000000..6d58e1b --- /dev/null +++ b/ports/mips/vsprintf.c @@ -0,0 +1,244 @@ +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + * and Himanshu Fucked it up further :)) + */ + +#include +#include "system.h" +#include "atomport.h" + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const int8_t **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +/*#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; })*/ + +static uint32_t do_div (int32_t *n, int32_t base) +{ + uint32_t remainder = *n % base; + *n /= base; + return remainder; +} + +static int8_t * number(int8_t * str, int32_t num, int32_t base, + int32_t size, int32_t precision, int32_t type) +{ + int8_t c,sign,tmp[36]; + const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int32_t i; + + if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; + if (type & LEFT) type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type & SIGN && num < 0) { + sign = '-'; + num = -num; + } else + sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); + if (sign) size--; + + if (type & SPECIAL) { + if (base == 16) { + size -= 2; + } else if (base == 8) { + size--; + } + } + + i = 0; + if (num == 0) + tmp[i++] = '0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while(size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) { + *str++ = '0'; + } else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while(size-- > 0) + *str++ = c; + while(i < precision--) + *str++ = '0'; + while(i-- > 0) + *str++ = tmp[i]; + while(size-- > 0) + *str++ = ' '; + return str; +} + +int vsprintf (int8_t *buf, const int8_t *fmt, va_list args) +{ + int32_t len; + int32_t i; + int8_t * str; + int8_t *s; + int32_t *ip; + + int32_t flags; /* flags to number() */ + + int32_t field_width; /* width of output field */ + int32_t precision; /* min. # of digits for integers; max + number of chars for from string */ + int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, int8_t *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int32_t *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} From c031dcf6412d65c4f8cb989b4e2c858c3664be8d Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 4 Jul 2011 19:35:16 +0530 Subject: [PATCH 44/76] Initial code for ARM7a port. Signed-off-by: Anup Patel --- ports/arm7a/Doxyfile | 1161 ++++++++++++++++++++++++++++++++ ports/arm7a/Makefile | 156 +++++ ports/arm7a/arm_config.h | 147 ++++ ports/arm7a/arm_entry.s | 212 ++++++ ports/arm7a/arm_gic.c | 208 ++++++ ports/arm7a/arm_gic.h | 62 ++ ports/arm7a/arm_io.h | 45 ++ ports/arm7a/arm_irq.c | 151 +++++ ports/arm7a/arm_irq.h | 55 ++ ports/arm7a/arm_main.c | 238 +++++++ ports/arm7a/arm_plat.h | 287 ++++++++ ports/arm7a/arm_timer.c | 102 +++ ports/arm7a/arm_timer.h | 56 ++ ports/arm7a/arm_uart.c | 112 +++ ports/arm7a/arm_uart.h | 110 +++ ports/arm7a/atomport-asm.s | 58 ++ ports/arm7a/atomport-private.h | 53 ++ ports/arm7a/atomport-tests.h | 48 ++ ports/arm7a/atomport.c | 58 ++ ports/arm7a/atomport.h | 110 +++ ports/arm7a/linker.ld | 138 ++++ ports/arm7a/printk.c | 59 ++ ports/arm7a/printk.h | 42 ++ ports/arm7a/stdarg.h | 28 + ports/arm7a/string.c | 61 ++ ports/arm7a/string.h | 42 ++ ports/arm7a/system.h | 52 ++ ports/arm7a/vsprintf.c | 244 +++++++ 28 files changed, 4095 insertions(+) create mode 100644 ports/arm7a/Doxyfile create mode 100644 ports/arm7a/Makefile create mode 100644 ports/arm7a/arm_config.h create mode 100644 ports/arm7a/arm_entry.s create mode 100644 ports/arm7a/arm_gic.c create mode 100644 ports/arm7a/arm_gic.h create mode 100644 ports/arm7a/arm_io.h create mode 100644 ports/arm7a/arm_irq.c create mode 100644 ports/arm7a/arm_irq.h create mode 100644 ports/arm7a/arm_main.c create mode 100644 ports/arm7a/arm_plat.h create mode 100644 ports/arm7a/arm_timer.c create mode 100644 ports/arm7a/arm_timer.h create mode 100644 ports/arm7a/arm_uart.c create mode 100644 ports/arm7a/arm_uart.h create mode 100644 ports/arm7a/atomport-asm.s create mode 100644 ports/arm7a/atomport-private.h create mode 100644 ports/arm7a/atomport-tests.h create mode 100644 ports/arm7a/atomport.c create mode 100644 ports/arm7a/atomport.h create mode 100755 ports/arm7a/linker.ld create mode 100644 ports/arm7a/printk.c create mode 100644 ports/arm7a/printk.h create mode 100755 ports/arm7a/stdarg.h create mode 100644 ports/arm7a/string.c create mode 100644 ports/arm7a/string.h create mode 100644 ports/arm7a/system.h create mode 100644 ports/arm7a/vsprintf.c diff --git a/ports/arm7a/Doxyfile b/ports/arm7a/Doxyfile new file mode 100644 index 0000000..e6f6571 --- /dev/null +++ b/ports/arm7a/Doxyfile @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = atomthreads + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen-avr + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile new file mode 100644 index 0000000..db3f78d --- /dev/null +++ b/ports/arm7a/Makefile @@ -0,0 +1,156 @@ +############ +# Settings # +############ + +# Build all test applications: +# make +# +# Program a test application using UISP (appname => test app e.g. sems1): +# make program app=appname + +# Location of build tools and atomthreads sources +KERNEL_DIR=../../kernel +TESTS_DIR=../../tests + +CPU=cortex-a8 +BOARD=pb-a8 +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy + +# Check if verbosity is ON for build process +VERBOSE_DEFAULT := 0 +CMD_PREFIX_DEFAULT := @ +ifdef VERBOSE + ifeq ("$(origin VERBOSE)", "command line") + VB := $(VERBOSE) + else + VB := $(VERBOSE_DEFAULT) + endif +else + VB := $(VERBOSE_DEFAULT) +endif +ifeq ($(VB), 1) + V := +else + V := $(CMD_PREFIX_DEFAULT) +endif + +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Directory for built objects +BUILD_DIR=build + +# Port/application object files +APP_OBJECTS = arm_irq.o +APP_OBJECTS += arm_gic.o +APP_OBJECTS += arm_timer.o +APP_OBJECTS += arm_uart.o +APP_OBJECTS += arm_main.o +APP_OBJECTS += atomport.o +APP_OBJECTS += printk.o +APP_OBJECTS += string.o +APP_OBJECTS += vsprintf.o +APP_ASM_OBJECTS = arm_entry.o +APP_ASM_OBJECTS += atomport-asm.o + +# Kernel object files +KERNEL_OBJECTS = atomkernel.o +KERNEL_OBJECTS += atomsem.o +KERNEL_OBJECTS += atommutex.o +KERNEL_OBJECTS += atomtimer.o +KERNEL_OBJECTS += atomqueue.o + +# Collection of built objects (excluding test applications) +ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) +BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) + +# Test object files (dealt with separately as only one per application build) +TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c))) + +# Target application filenames (.elf and .hex) for each test object +TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) +TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS)) + +# Search build/output directory for dependencies +vpath %.o ./$(BUILD_DIR) +vpath %.elf ./$(BUILD_DIR) +vpath %.hex ./$(BUILD_DIR) + +# GCC flags +CFLAGS= -g \ + -Wall \ + -Werror \ + -O \ + -mcpu=$(CPU) \ + -fstrength-reduce \ + -fomit-frame-pointer \ + -finline-functions \ + -nostdinc \ + -fno-builtin \ + -fno-stack-protector + +# Enable stack-checking (disable if not required) +ifeq ($(STACK_CHECK),true) +CFLAGS += -DATOM_STACK_CHECKING +endif + +################# +# Build targets # +################# + +# All tests +all: $(BUILD_DIR) $(TEST_HEXS) Makefile + +# Make build/output directory +$(BUILD_DIR): + mkdir $(BUILD_DIR) + +# Test HEX files (one application build for each test) +$(TEST_HEXS): %.hex: %.elf + $(if $(V), @echo " (HEX) $(subst $(build_dir)/,,$@)") + $(V)$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ + +# Test ELF files (one application build for each test) +$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(BUILD_DIR)/$@ -Wl -T linker.ld + +# Kernel objects builder +$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Test objects builder +$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application C objects builder +$(APP_OBJECTS): %.o: ./%.c + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# Application asm objects builder +$(APP_ASM_OBJECTS): %.o: ./%.s + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + +# .lst file builder +%.lst: %.c + $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + +# Clean +clean: + $(V)rm -f *.o *.elf *.map *.hex *.bin *.lst + rm -rf doxygen-kernel + rm -rf doxygen-avr + rm -rf build + +doxygen: + doxygen $(KERNEL_DIR)/Doxyfile + doxygen ./Doxyfile diff --git a/ports/arm7a/arm_config.h b/ports/arm7a/arm_config.h new file mode 100644 index 0000000..d4e9e99 --- /dev/null +++ b/ports/arm7a/arm_config.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2011 Anup Patel. + * All rights reserved. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * @file arm_config.h + * @version 1.0 + * @author Anup Patel (anup@brainfault.org) + * @brief ARM Platform Configuration Header + */ +#ifndef _ARM_CONFIG_H__ +#define _ARM_CONFIG_H__ + +/* + * Peripheral addresses + */ +#define REALVIEW_PBA8_UART0_BASE 0x10009000 /* UART 0 */ +#define REALVIEW_PBA8_UART1_BASE 0x1000A000 /* UART 1 */ +#define REALVIEW_PBA8_UART2_BASE 0x1000B000 /* UART 2 */ +#define REALVIEW_PBA8_UART3_BASE 0x1000C000 /* UART 3 */ +#define REALVIEW_PBA8_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ +#define REALVIEW_PBA8_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ +#define REALVIEW_PBA8_WATCHDOG_BASE 0x10010000 /* watchdog interface */ +#define REALVIEW_PBA8_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ +#define REALVIEW_PBA8_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ +#define REALVIEW_PBA8_GPIO0_BASE 0x10013000 /* GPIO port 0 */ +#define REALVIEW_PBA8_RTC_BASE 0x10017000 /* Real Time Clock */ +#define REALVIEW_PBA8_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ +#define REALVIEW_PBA8_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ +#define REALVIEW_PBA8_SCTL_BASE 0x1001A000 /* System Controller */ +#define REALVIEW_PBA8_CLCD_BASE 0x10020000 /* CLCD */ +#define REALVIEW_PBA8_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ +#define REALVIEW_PBA8_DMC_BASE 0x100E0000 /* DMC configuration */ +#define REALVIEW_PBA8_SMC_BASE 0x100E1000 /* SMC configuration */ +#define REALVIEW_PBA8_CAN_BASE 0x100E2000 /* CAN bus */ +#define REALVIEW_PBA8_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */ +#define REALVIEW_PBA8_FLASH0_BASE 0x40000000 +#define REALVIEW_PBA8_FLASH0_SIZE SZ_64M +#define REALVIEW_PBA8_FLASH1_BASE 0x44000000 +#define REALVIEW_PBA8_FLASH1_SIZE SZ_64M +#define REALVIEW_PBA8_ETH_BASE 0x4E000000 /* Ethernet */ +#define REALVIEW_PBA8_USB_BASE 0x4F000000 /* USB */ +#define REALVIEW_PBA8_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ +#define REALVIEW_PBA8_LT_BASE 0xC0000000 /* Logic Tile expansion */ +#define REALVIEW_PBA8_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ +#define REALVIEW_PBA8_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ + +#define REALVIEW_PBA8_SYS_PLD_CTRL1 0x74 + +/* + * PBA8 PCI regions + */ +#define REALVIEW_PBA8_PCI_BASE 0x90040000 /* PCI-X Unit base */ +#define REALVIEW_PBA8_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ +#define REALVIEW_PBA8_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ + +#define REALVIEW_PBA8_PCI_BASE_SIZE 0x10000 /* 16 Kb */ +#define REALVIEW_PBA8_PCI_IO_SIZE 0x1000 /* 4 Kb */ +#define REALVIEW_PBA8_PCI_MEM_SIZE 0x20000000 /* 512 MB */ + +/* + * Irqs + */ +#define IRQ_PBA8_GIC_START 32 + +/* L220 +#define IRQ_PBA8_L220_EVENT (IRQ_PBA8_GIC_START + 29) +#define IRQ_PBA8_L220_SLAVE (IRQ_PBA8_GIC_START + 30) +#define IRQ_PBA8_L220_DECODE (IRQ_PBA8_GIC_START + 31) +*/ + +/* + * PB-A8 on-board gic irq sources + */ +#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ +#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ +#define IRQ_PBA8_COMMRx (IRQ_PBA8_GIC_START + 2) /* Debug Comm Rx interrupt */ +#define IRQ_PBA8_COMMTx (IRQ_PBA8_GIC_START + 3) /* Debug Comm Tx interrupt */ +#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 4) /* Timer 0/1 (default timer) */ +#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 5) /* Timer 2/3 */ +#define IRQ_PBA8_GPIO0 (IRQ_PBA8_GIC_START + 6) /* GPIO 0 */ +#define IRQ_PBA8_GPIO1 (IRQ_PBA8_GIC_START + 7) /* GPIO 1 */ +#define IRQ_PBA8_GPIO2 (IRQ_PBA8_GIC_START + 8) /* GPIO 2 */ + /* 9 reserved */ +#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 10) /* Real Time Clock */ +#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ +#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 12) /* UART 0 on development chip */ +#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 13) /* UART 1 on development chip */ +#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 14) /* UART 2 on development chip */ +#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 15) /* UART 3 on development chip */ +#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ +#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ +#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ +#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ +#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ +#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ +#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ +#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ +#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ +#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ +#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ +#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ +#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ +#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ +#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ +#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ + +/* ... */ +#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) +#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) +#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) +#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) + +#define IRQ_PBA8_SMC -1 +#define IRQ_PBA8_SCTL -1 + +#define NR_GIC_PBA8 1 + +/* + * Only define NR_IRQS if less than NR_IRQS_PBA8 + */ +#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) + +#if !defined(ARM_GIC_NR_IRQS) || (ARM_GIC_NR_IRQS < NR_IRQS_PBA8) +#undef ARM_GIC_NR_IRQS +#define ARM_GIC_NR_IRQS NR_IRQS_PBA8 +#endif + +#if !defined(ARM_GIC_MAX_NR) || (REALVIEW_GIC_MAX_NR < NR_GIC_PBA8) +#undef ARM_GIC_MAX_NR +#define ARM_GIC_MAX_NR NR_GIC_PBA8 +#endif + +#endif diff --git a/ports/arm7a/arm_entry.s b/ports/arm7a/arm_entry.s new file mode 100644 index 0000000..c19d651 --- /dev/null +++ b/ports/arm7a/arm_entry.s @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + +.macro SET_CURRENT_FLAGS flags, treg + mrs \treg, cpsr + orr \treg, \treg, #(\flags) + msr cpsr, \treg +.endm + +.macro SET_CURRENT_MODE mode + cps #(\mode) +.endm + +.macro SET_CURRENT_STACK new_stack + ldr sp, \new_stack +.endm + +.macro START_EXCEPTION_HANDLER irqname, lroffset + .align 5 +\irqname: + sub lr, lr, #\lroffset +.endm + +/* Save User Registers */ +.macro PUSH_USER_REGS + str lr, [sp, #-4]!; /* Push the return address */ + sub sp, sp, #(4*15); /* Adjust the stack pointer */ + stmia sp, {r0-r12}; /* Push user mode registers */ + add r0, sp, #(4*13); /* Adjust the stack pointer */ + stmia r0, {r13-r14}^; /* Push user mode registers */ + mov r0, r0; /* NOP for previous inst */ + mrs r0, spsr_all; /* Put the SPSR on the stack */ + str r0, [sp, #-4]! +.endm + +/* Save User Registers in FIQ */ +.macro PUSH_FIQUSER_REGS + str lr, [sp, #-4]!; /* Push the return address */ + sub sp, sp, #(4*15); /* Adjust the stack pointer */ + stmia sp, {r0-r7}; /* Push user mode registers */ + add r0, sp, #(4*8); /* Adjust the stack pointer */ + stmia r0, {r8-r14}^; /* Push user mode registers */ + mov r0, r0; /* NOP for previous inst */ + mrs r0, spsr_all; /* Put the SPSR on the stack */ + str r0, [sp, #-4]! +.endm + +/* Call C function to handle exception */ +.macro CALL_EXCEPTION_CFUNC cfunc + mov r0, sp + bl \cfunc +.endm + +/* Restore User Registers */ +.macro PULL_USER_REGS + ldr r0, [sp], #0x0004; /* Get SPSR from stack */ + msr spsr_all, r0; + ldmia sp, {r0-r14}^; /* Restore registers (user) */ + mov r0, r0; /* NOP for previous isnt */ + add sp, sp, #(4*15); /* Adjust the stack pointer */ + ldr lr, [sp], #0x0004 /* Pull return address */ +.endm + +.macro END_EXCEPTION_HANDLER + movs pc, lr +.endm + + .section .expvect, "ax", %progbits + .globl _start_vect +_start_vect: + ldr pc, __reset + ldr pc, __undefined_instruction + ldr pc, __software_interrupt + ldr pc, __prefetch_abort + ldr pc, __data_abort + ldr pc, __not_used + ldr pc, __irq + ldr pc, __fiq +__reset: + .word _reset +__undefined_instruction: + .word _undefined_instruction +__software_interrupt: + .word _software_interrupt +__prefetch_abort: + .word _prefetch_abort +__data_abort: + .word _data_abort +__not_used: + .word _not_used +__irq: + .word _irq +__fiq: + .word _fiq + .global _end_vect +_end_vect: + +__svc_stack_end: + .word _svc_stack_end +__und_stack_end: + .word _und_stack_end +__abt_stack_end: + .word _abt_stack_end +__irq_stack_end: + .word _irq_stack_end +__fiq_stack_end: + .word _fiq_stack_end +__usr_stack_end: + .word _usr_stack_end + + .globl _reset +_reset: + /* Clear a register for temporary usage */ + mov r8, #0 + /* Disable IRQ & FIQ */ + cpsid if + /* Set Supervisor Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_SUPERVISOR + SET_CURRENT_STACK __svc_stack_end + /* Set Undefined Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_UNDEFINED + SET_CURRENT_STACK __und_stack_end + /* Set Abort Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_ABORT + SET_CURRENT_STACK __abt_stack_end + /* Set IRQ Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_IRQ + SET_CURRENT_STACK __irq_stack_end + /* Set FIQ Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_FIQ + SET_CURRENT_STACK __fiq_stack_end + /* Set System Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_SYSTEM + SET_CURRENT_STACK __usr_stack_end + /* Set to Supervisor Mode */ + SET_CURRENT_MODE CPSR_MODE_SUPERVISOR + /* Call main function */ + bl main + /* We should never reach here */ + b . + + +START_EXCEPTION_HANDLER _undefined_instruction, 4 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_undefined_instruction + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _software_interrupt, 4 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_software_interrupt + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _prefetch_abort, 4 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_prefetch_abort + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _data_abort, 8 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_data_abort + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _not_used, 4 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_not_used + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _irq, 4 + PUSH_USER_REGS + CALL_EXCEPTION_CFUNC do_irq + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _fiq, 4 + PUSH_FIQUSER_REGS + CALL_EXCEPTION_CFUNC do_fiq + PULL_USER_REGS +END_EXCEPTION_HANDLER + diff --git a/ports/arm7a/arm_gic.c b/ports/arm7a/arm_gic.c new file mode 100644 index 0000000..773d869 --- /dev/null +++ b/ports/arm7a/arm_gic.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +#define max(a,b) ((a) < (b) ? (b) : (a)) + +struct gic_chip_data { + uint32_t irq_offset; + virtual_addr_t dist_base; + virtual_addr_t cpu_base; +}; + +static struct gic_chip_data gic_data[ARM_GIC_MAX_NR]; + +static inline void arm_gic_write(uint32_t val, virtual_addr_t addr) +{ + arm_writel(val, (void *)(addr)); +} + +static inline uint32_t arm_gic_read(virtual_addr_t addr) +{ + return arm_readl((void *)(addr)); +} + +int arm_gic_active_irq(uint32_t gic_nr) +{ + int ret = -1; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + ret = arm_gic_read(gic_data[gic_nr].cpu_base + + GIC_CPU_INTACK) & 0x3FF; + ret += gic_data[gic_nr].irq_offset; + + return ret; +} + +int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); + arm_gic_write(gic_irq, gic_data[gic_nr].cpu_base + GIC_CPU_EOI); + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_mask(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_unmask(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start) +{ + unsigned int max_irq, i; + uint32_t cpumask = 1 << 0; /*smp_processor_id(); */ + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + + gic_data[gic_nr].dist_base = base; + gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; + + arm_gic_write(0, base + GIC_DIST_CTRL); + + /* + * Find out how many interrupts are supported. + */ + max_irq = arm_gic_read(base + GIC_DIST_CTR) & 0x1f; + max_irq = (max_irq + 1) * 32; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (max_irq > max(1020, ARM_GIC_NR_IRQS)) + max_irq = max(1020, ARM_GIC_NR_IRQS); + + /* + * Set all global interrupts to be level triggered, active low. + */ + for (i = 32; i < max_irq; i += 16) + arm_gic_write(0, base + GIC_DIST_CONFIG + i * 4 / 16); + + /* + * Set all global interrupts to this CPU only. + */ + for (i = 32; i < max_irq; i += 4) + arm_gic_write(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); + + /* + * Set priority on all interrupts. + */ + for (i = 0; i < max_irq; i += 4) + arm_gic_write(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); + + /* + * Disable all interrupts. + */ + for (i = 0; i < max_irq; i += 32) + arm_gic_write(0xffffffff, + base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); + + arm_gic_write(1, base + GIC_DIST_CTRL); + + return 0; +} + +int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base) +{ + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + gic_data[gic_nr].cpu_base = base; + + arm_gic_write(0xf0, base + GIC_CPU_PRIMASK); + arm_gic_write(1, base + GIC_CPU_CTRL); + + return 0; +} diff --git a/ports/arm7a/arm_gic.h b/ports/arm7a/arm_gic.h new file mode 100644 index 0000000..cca8c77 --- /dev/null +++ b/ports/arm7a/arm_gic.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_GIC_H__ +#define _ARM_GIC_H__ + +#include +#include + +#define GIC_CPU_CTRL 0x00 +#define GIC_CPU_PRIMASK 0x04 +#define GIC_CPU_BINPOINT 0x08 +#define GIC_CPU_INTACK 0x0c +#define GIC_CPU_EOI 0x10 +#define GIC_CPU_RUNNINGPRI 0x14 +#define GIC_CPU_HIGHPRI 0x18 + +#define GIC_DIST_CTRL 0x000 +#define GIC_DIST_CTR 0x004 +#define GIC_DIST_ENABLE_SET 0x100 +#define GIC_DIST_ENABLE_CLEAR 0x180 +#define GIC_DIST_PENDING_SET 0x200 +#define GIC_DIST_PENDING_CLEAR 0x280 +#define GIC_DIST_ACTIVE_BIT 0x300 +#define GIC_DIST_PRI 0x400 +#define GIC_DIST_TARGET 0x800 +#define GIC_DIST_CONFIG 0xc00 +#define GIC_DIST_SOFTINT 0xf00 + +int arm_gic_active_irq(uint32_t gic_nr); +int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq); +int arm_gic_mask(uint32_t gic_nr, uint32_t irq); +int arm_gic_unmask(uint32_t gic_nr, uint32_t irq); +int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start); +int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base); + +#endif diff --git a/ports/arm7a/arm_io.h b/ports/arm7a/arm_io.h new file mode 100644 index 0000000..950a938 --- /dev/null +++ b/ports/arm7a/arm_io.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IO_H_ +#define __ARM_IO_H_ + +#include + +static inline uint32_t arm_readl(void * addr) +{ + return *((uint32_t *)addr); +} + +static inline void arm_writel(uint32_t data, void * addr) +{ + *((uint32_t *)addr) = data; +} + +#endif /* __ARM_IO_H_ */ diff --git a/ports/arm7a/arm_irq.c b/ports/arm7a/arm_irq.c new file mode 100644 index 0000000..153bad2 --- /dev/null +++ b/ports/arm7a/arm_irq.c @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; + +void do_undefined_instruction(pt_regs_t *regs) +{ +} + +void do_software_interrupt(pt_regs_t *regs) +{ +} + +void do_prefetch_abort(pt_regs_t *regs) +{ +} + +void do_data_abort(pt_regs_t *regs) +{ +} + +void do_not_used(pt_regs_t *regs) +{ +} + +void do_irq(pt_regs_t *uregs) +{ + int rc = 0; + int irq = arm_gic_active_irq(0); + + if (-1 < irq) { + if (irq_hndls[irq]) { + rc = irq_hndls[irq](irq, uregs); + if (rc) { + while (1); + } + } + rc = arm_gic_ack_irq(0, irq); + if (rc) { + while (1); + } + } +} + +void do_fiq(pt_regs_t *uregs) +{ +} + +void arm_irq_setup(void) +{ + extern uint32_t _start_vect[]; + uint32_t *vectors = (uint32_t *)NULL; + uint32_t *vectors_data = vectors + CPU_IRQ_NR; + int vec; + + /* + * Loop through the vectors we're taking over, and copy the + * vector's insn and data word. + */ + for (vec = 0; vec < CPU_IRQ_NR; vec++) { + vectors[vec] = _start_vect[vec]; + vectors_data[vec] = _start_vect[vec+CPU_IRQ_NR]; + } + + /* + * Check if verctors are set properly + */ + for (vec = 0; vec < CPU_IRQ_NR; vec++) { + if ((vectors[vec] != _start_vect[vec]) || + (vectors_data[vec] != _start_vect[vec+CPU_IRQ_NR])) { + /* Hang */ + while(1); + } + } + + /* + * Reset irq handlers + */ + for (vec = 0; vec < NR_IRQS_PBA8; vec++) { + irq_hndls[vec] = NULL; + } + + /* + * Initialize Generic Interrupt Controller + */ + vec = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, + IRQ_PBA8_GIC_START); + if (vec) { + while(1); + } + vec = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + if (vec) { + while(1); + } +} + +void arm_irq_register(uint32_t irq, arm_irq_handler_t hndl) +{ + int rc = 0; + if (irq < NR_IRQS_PBA8) { + irq_hndls[irq] = hndl; + if (irq_hndls[irq]) { + rc = arm_gic_unmask(0, irq); + if (rc) { + while (1); + } + } + } +} + +void arm_irq_enable(void) +{ + __asm( "cpsie if" ); +} + +void arm_irq_disable(void) +{ + __asm( "cpsid if" ); +} + diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h new file mode 100644 index 0000000..bad336d --- /dev/null +++ b/ports/arm7a/arm_irq.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IRQ_H +#define __ARM_IRQ_H + +#include +#include + +typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); + +#define CPU_IRQ_NR 8 + +/** IRQ Numbers */ +#define ARM_RESET_IRQ 0 +#define ARM_UNDEF_INST_IRQ 1 +#define ARM_SOFT_IRQ 2 +#define ARM_PREFETCH_ABORT_IRQ 3 +#define ARM_DATA_ABORT_IRQ 4 +#define ARM_NOT_USED_IRQ 5 +#define ARM_EXTERNAL_IRQ 6 +#define ARM_EXTERNAL_FIQ 7 + +void arm_irq_setup(void); +void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); +void arm_irq_enable(void); +void arm_irq_disable(void); + +#endif /* __ARM_IRQ_H */ diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c new file mode 100644 index 0000000..7cfd526 --- /dev/null +++ b/ports/arm7a/arm_main.c @@ -0,0 +1,238 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include +#include +#include "system.h" +#include +#include +#include + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + * + * In this case, the idle stack is allocated on the BSS via the + * idle_thread_stack[] byte array. + */ +#define IDLE_STACK_SIZE_BYTES 8192 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop + * flashing a LED. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + * + * With all OS tests implemented to date on the AVR, the Main thread + * stack has not exceeded 198 bytes. To allow all tests to run we set + * a minimum main thread stack size of 204 bytes. This may increase in + * future as the codebase changes but for the time being is enough to + * cope with all of the automated tests. + */ +#define MAIN_STACK_SIZE_BYTES 8192 + + +/* + * Startup code stack + * + * Some stack space is required at initial startup for running the main() + * routine. This stack space is only temporarily required at first bootup + * and is no longer required as soon as the OS is started. By default + * GCC sets this to the top of RAM (RAMEND) and it grows down from there. + * Because we only need this temporarily, though, it would be wasteful to + * set aside a region at the top of RAM which is not used during runtime. + * + * What we do here is to reuse part of the idle thread's stack during + * initial startup. As soon as we enter the main() routine we move the + * stack pointer to half-way down the idle thread's stack. This is used + * temporarily while calls are made to atomOSInit(), atomThreadCreate() + * and atomOSStart(). Once the OS is started this stack area is no + * longer required, and can be used for its original purpose (for the + * idle thread's stack). + * + * This does mean, however, that we cannot monitor the stack usage of the + * idle thread. Stack usage is monitored by prefilling the stack with a + * known value, and we are obliterating some of that prefilled area by + * using it as our startup stack, so we cannot use the stack-checking API + * to get a true picture of idle thread stack usage. If you wish to + * monitor idle thread stack usage for your applications then you are + * free to use a different region for the startup stack (e.g. set aside + * an area permanently, or place it somewhere you know you can reuse + * later in the application). For the time being, this method gives us a + * simple way of reducing the memory consumption without having to add + * any special AVR-specific considerations to the automated test + * applications. + * + * This optimisation was required to allow some of the larger automated + * test modules to run on devices with 1KB of RAM. You should avoid doing + * this if you can afford to set aside 64 bytes or so, or if you are + * writing your own applications in which you have further control over + * where data is located. + */ + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + +/* Global Data */ +uint32_t at_preempt_count; + +/** + * \b main + * + * Program entry point. + * + * Sets up the AVR hardware resources (system tick timer interrupt) necessary + * for the OS to be started. Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + at_preempt_count = 0; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /** + * Initialise the OS before creating our threads. + * + * Note that we tell the OS that the idle stack is half its actual + * size. This prevents it prefilling the bottom half with known + * values for stack-checkig purposes, which we cannot allow because + * we are temporarily using it for our own stack. The remainder will + * still be available once the OS is started, this only prevents the + * OS from prefilling it. + * + * If you are not reusing the idle thread's stack during startup then + * you should pass in the correct size here. + */ + status = atomOSInit(&idle_thread_stack[0], + IDLE_STACK_SIZE_BYTES, 0); + if (status == ATOM_OK) + { + arm_irq_setup(); + + arm_irq_enable(); + + arm_timer_init(1000, 1); + + arm_uart_init(); + + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, 0); + if (status == ATOM_OK) + { + arm_timer_enable(); + + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1); + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + while (1) { + /* Put a message out on the UART */ + printk("Running Tests... "); + if (test_start() != 0) { + printk("FAILED!\n"); + } else { + printk("SUCCESS!\n"); + } + } +} diff --git a/ports/arm7a/arm_plat.h b/ports/arm7a/arm_plat.h new file mode 100644 index 0000000..b226955 --- /dev/null +++ b/ports/arm7a/arm_plat.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_PLAT_H__ +#define _ARM_PLAT_H__ + +/* + * Memory definitions + */ +#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ +#define REALVIEW_BOOT_ROM_HI 0x30000000 +#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ +#define REALVIEW_BOOT_ROM_SIZE SZ_64M + +#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ +#define REALVIEW_SSRAM_SIZE SZ_2M + +/* + * SDRAM + */ +#define REALVIEW_SDRAM_BASE 0x00000000 + +/* + * Logic expansion modules + * + */ + +/* ------------------------------------------------------------------------ + * RealView Registers + * ------------------------------------------------------------------------ + * + */ +#define REALVIEW_SYS_ID_OFFSET 0x00 +#define REALVIEW_SYS_SW_OFFSET 0x04 +#define REALVIEW_SYS_LED_OFFSET 0x08 +#define REALVIEW_SYS_OSC0_OFFSET 0x0C + +#define REALVIEW_SYS_OSC1_OFFSET 0x10 +#define REALVIEW_SYS_OSC2_OFFSET 0x14 +#define REALVIEW_SYS_OSC3_OFFSET 0x18 +#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ + +#define REALVIEW_SYS_LOCK_OFFSET 0x20 +#define REALVIEW_SYS_100HZ_OFFSET 0x24 +#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 +#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C +#define REALVIEW_SYS_FLAGS_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 +#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C +#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 +#define REALVIEW_SYS_PCICTL_OFFSET 0x44 +#define REALVIEW_SYS_MCI_OFFSET 0x48 +#define REALVIEW_SYS_FLASH_OFFSET 0x4C +#define REALVIEW_SYS_CLCD_OFFSET 0x50 +#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 +#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 +#define REALVIEW_SYS_24MHz_OFFSET 0x5C +#define REALVIEW_SYS_MISC_OFFSET 0x60 +#define REALVIEW_SYS_IOSEL_OFFSET 0x70 +#define REALVIEW_SYS_PROCID_OFFSET 0x84 +#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 +#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 +#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 +#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC +#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 + +#define REALVIEW_SYS_BASE 0x10000000 +#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) +#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) +#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) +#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) +#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) + +#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) +#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) +#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) +#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) +#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) +#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) +#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) +#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) +#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) +#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) +#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) +#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) +#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) +#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) +#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) +#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) +#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) +#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) +#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) +#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) +#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) +#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) +#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) +#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) +#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) +#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) + +/* + * Values for REALVIEW_SYS_RESET_CTRL + */ +#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01 +#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02 +#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03 +#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04 +#define REALVIEW_SYS_CTRL_RESET_POR 0x05 +#define REALVIEW_SYS_CTRL_RESET_DoC 0x06 + +#define REALVIEW_SYS_CTRL_LED (1 << 0) + +/* ------------------------------------------------------------------------ + * RealView control registers + * ------------------------------------------------------------------------ + */ + +/* + * REALVIEW_IDFIELD + * + * 31:24 = manufacturer (0x41 = ARM) + * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) + * 15:12 = FPGA (0x3 = XVC600 or XVC600E) + * 11:4 = build value + * 3:0 = revision number (0x1 = rev B (AHB)) + */ + +/* + * REALVIEW_SYS_LOCK + * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, + * SYS_CLD, SYS_BOOTCS + */ +#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) +#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ + +/* + * REALVIEW_SYS_FLASH + */ +#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ + +/* + * REALVIEW_INTREG + * - used to acknowledge and control MMCI and UART interrupts + */ +#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ +#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ +#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ + /* write 1 to acknowledge and clear */ +#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ +#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ + +/* + * RealView common peripheral addresses + */ +#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */ +#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */ +#define REALVIEW_AACI_BASE 0x10004000 /* Audio */ +#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */ +#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */ +#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */ +#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */ +#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */ +#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */ +#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */ +#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */ +#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */ + +/* PCI space */ +#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */ +#define REALVIEW_PCI_CFG_BASE 0x42000000 +#define REALVIEW_PCI_MEM_BASE0 0x44000000 +#define REALVIEW_PCI_MEM_BASE1 0x50000000 +#define REALVIEW_PCI_MEM_BASE2 0x60000000 +/* Sizes of above maps */ +#define REALVIEW_PCI_BASE_SIZE 0x01000000 +#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000 +#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */ +#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */ +#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */ + +#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */ +#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */ + +/* + * CompactFlash + */ +#define REALVIEW_CF_BASE 0x18000000 /* CompactFlash */ +#define REALVIEW_CF_MEM_BASE 0x18003000 /* SMC for CompactFlash */ + +/* + * Disk on Chip + */ +#define REALVIEW_DOC_BASE 0x2C000000 +#define REALVIEW_DOC_SIZE (16 << 20) +#define REALVIEW_DOC_PAGE_SIZE 512 +#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE) + +#define ERASE_UNIT_PAGES 32 +#define START_PAGE 0x80 + +/* + * LED settings, bits [7:0] + */ +#define REALVIEW_SYS_LED0 (1 << 0) +#define REALVIEW_SYS_LED1 (1 << 1) +#define REALVIEW_SYS_LED2 (1 << 2) +#define REALVIEW_SYS_LED3 (1 << 3) +#define REALVIEW_SYS_LED4 (1 << 4) +#define REALVIEW_SYS_LED5 (1 << 5) +#define REALVIEW_SYS_LED6 (1 << 6) +#define REALVIEW_SYS_LED7 (1 << 7) + +#define ALL_LEDS 0xFF + +#define LED_BANK REALVIEW_SYS_LED + +/* + * Control registers + */ +#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ +#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ +#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ +#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ + +/* + * Clean base - dummy + * + */ +#define CLEAN_BASE REALVIEW_BOOT_ROM_HI + +/* + * System controller bit assignment + */ +#define REALVIEW_REFCLK 0 +#define REALVIEW_TIMCLK 1 + +#define REALVIEW_TIMER1_EnSel 15 +#define REALVIEW_TIMER2_EnSel 17 +#define REALVIEW_TIMER3_EnSel 19 +#define REALVIEW_TIMER4_EnSel 21 + +#define MAX_TIMER 2 +#define MAX_PERIOD 699050 +#define TICKS_PER_uSEC 1 + +/* + * These are useconds NOT ticks. + * + */ +#define mSEC_1 1000 +#define mSEC_5 (mSEC_1 * 5) +#define mSEC_10 (mSEC_1 * 10) +#define mSEC_25 (mSEC_1 * 25) +#define SEC_1 (mSEC_1 * 1000) + +#define REALVIEW_CSR_BASE 0x10000000 +#define REALVIEW_CSR_SIZE 0x10000000 + +#endif diff --git a/ports/arm7a/arm_timer.c b/ports/arm7a/arm_timer.c new file mode 100644 index 0000000..8a64676 --- /dev/null +++ b/ports/arm7a/arm_timer.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include +#include +#include +#include + +unsigned long long jiffies; + +void arm_timer_enable(void) +{ + uint32_t ctrl; + + ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + ctrl |= TIMER_CTRL_ENABLE; + arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); +} + +void arm_timer_disable(void) +{ + uint32_t ctrl; + + ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + ctrl &= ~TIMER_CTRL_ENABLE; + arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); +} + +void arm_timer_clearirq(void) +{ + arm_writel(1, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_INTCLR)); +} + +int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the OS system tick handler */ + atomTimerTick(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); + + arm_timer_clearirq(); + + return 0; +} + +int arm_timer_init(uint32_t usecs, uint32_t ensel) +{ + uint32_t val; + + /* + * set clock frequency: + * REALVIEW_REFCLK is 32KHz + * REALVIEW_TIMCLK is 1MHz + */ + val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << ensel); + arm_writel(val, (void *)REALVIEW_SCTL_BASE); + + /* Register interrupt handler */ + arm_irq_register(IRQ_PBA8_TIMER0_1, &arm_timer_irqhndl); + + val = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + val &= ~TIMER_CTRL_ENABLE; + val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); + arm_writel(val, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); + arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); + + return 0; +} diff --git a/ports/arm7a/arm_timer.h b/ports/arm7a/arm_timer.h new file mode 100644 index 0000000..45bf35c --- /dev/null +++ b/ports/arm7a/arm_timer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_TIMER_H +#define __ARM_TIMER_H + +#include + +#define TIMER_LOAD 0x00 +#define TIMER_VALUE 0x04 +#define TIMER_CTRL 0x08 +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR 0x0c +#define TIMER_RIS 0x10 +#define TIMER_MIS 0x14 +#define TIMER_BGLOAD 0x18 + +void arm_timer_enable(void); +void arm_timer_disable(void); +void arm_timer_clearirq(void); +int arm_timer_init(uint32_t usecs, uint32_t ensel); + +#endif /* __ARM_TIMER_H */ diff --git a/ports/arm7a/arm_uart.c b/ports/arm7a/arm_uart.c new file mode 100644 index 0000000..9b423fa --- /dev/null +++ b/ports/arm7a/arm_uart.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include + +void arm_uart_putc(uint8_t ch) +{ + unsigned int base = 0x10009000; + if(ch=='\n') { + /* Wait until there is space in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); + + /* Send the character */ + arm_writel('\r', (void*)(base + UART_PL01x_DR)); + } + + /* Wait until there is space in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); + + /* Send the character */ + arm_writel(ch, (void*)(base + UART_PL01x_DR)); +} + +uint8_t arm_uart_getc(void) +{ + unsigned int base = 0x10009000; + uint8_t data; + + /* Wait until there is data in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_RXFE); + + data = arm_readl((void*)(base + UART_PL01x_DR)); + + /* Check for an error flag */ + if (data & 0xFFFFFF00) { + /* Clear the error */ + arm_writel(0xFFFFFFFF, (void*)(base + UART_PL01x_ECR)); + return -1; + } + + return data; +} + +void arm_uart_init(void) +{ + unsigned int base = 0x10009000; + unsigned int baudrate = 115200; + unsigned int input_clock = 24000000; + unsigned int divider; + unsigned int temp; + unsigned int remainder; + unsigned int fraction; + + /* First, disable everything */ + arm_writel(0x0, (void*)(base + UART_PL011_CR)); + + /* + * Set baud rate + * + * IBRD = UART_CLK / (16 * BAUD_RATE) + * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) + * / (16 * BAUD_RATE)) + */ + temp = 16 * baudrate; + divider = input_clock / temp; + remainder = input_clock % temp; + temp = (8 * remainder) / baudrate; + fraction = (temp >> 1) + (temp & 1); + + arm_writel(divider, (void*)(base + UART_PL011_IBRD)); + arm_writel(fraction, (void*)(base + UART_PL011_FBRD)); + + /* Set the UART to be 8 bits, 1 stop bit, + * no parity, fifo enabled + */ + arm_writel((UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN), + (void*)(base + UART_PL011_LCRH)); + + /* Finally, enable the UART */ + arm_writel((UART_PL011_CR_UARTEN | + UART_PL011_CR_TXE | + UART_PL011_CR_RXE), + (void*)(base + UART_PL011_CR)); +} + diff --git a/ports/arm7a/arm_uart.h b/ports/arm7a/arm_uart.h new file mode 100644 index 0000000..67d47d1 --- /dev/null +++ b/ports/arm7a/arm_uart.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_UART_H_ +#define __ARM_UART_H_ + +#include + +/* + * ARM PrimeCell UART's (PL010 & PL011) + * ------------------------------------ + * + * Definitions common to both PL010 & PL011 + * + */ +#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ +#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ +#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ +#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ + +#define UART_PL01x_RSR_OE 0x08 +#define UART_PL01x_RSR_BE 0x04 +#define UART_PL01x_RSR_PE 0x02 +#define UART_PL01x_RSR_FE 0x01 + +#define UART_PL01x_FR_TXFE 0x80 +#define UART_PL01x_FR_RXFF 0x40 +#define UART_PL01x_FR_TXFF 0x20 +#define UART_PL01x_FR_RXFE 0x10 +#define UART_PL01x_FR_BUSY 0x08 +#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY) + +/* + * PL011 definitions + * + */ +#define UART_PL011_IBRD 0x24 +#define UART_PL011_FBRD 0x28 +#define UART_PL011_LCRH 0x2C +#define UART_PL011_CR 0x30 +#define UART_PL011_IMSC 0x38 +#define UART_PL011_PERIPH_ID0 0xFE0 + +#define UART_PL011_LCRH_SPS (1 << 7) +#define UART_PL011_LCRH_WLEN_8 (3 << 5) +#define UART_PL011_LCRH_WLEN_7 (2 << 5) +#define UART_PL011_LCRH_WLEN_6 (1 << 5) +#define UART_PL011_LCRH_WLEN_5 (0 << 5) +#define UART_PL011_LCRH_FEN (1 << 4) +#define UART_PL011_LCRH_STP2 (1 << 3) +#define UART_PL011_LCRH_EPS (1 << 2) +#define UART_PL011_LCRH_PEN (1 << 1) +#define UART_PL011_LCRH_BRK (1 << 0) + +#define UART_PL011_CR_CTSEN (1 << 15) +#define UART_PL011_CR_RTSEN (1 << 14) +#define UART_PL011_CR_OUT2 (1 << 13) +#define UART_PL011_CR_OUT1 (1 << 12) +#define UART_PL011_CR_RTS (1 << 11) +#define UART_PL011_CR_DTR (1 << 10) +#define UART_PL011_CR_RXE (1 << 9) +#define UART_PL011_CR_TXE (1 << 8) +#define UART_PL011_CR_LPE (1 << 7) +#define UART_PL011_CR_IIRLP (1 << 2) +#define UART_PL011_CR_SIREN (1 << 1) +#define UART_PL011_CR_UARTEN (1 << 0) + +#define UART_PL011_IMSC_OEIM (1 << 10) +#define UART_PL011_IMSC_BEIM (1 << 9) +#define UART_PL011_IMSC_PEIM (1 << 8) +#define UART_PL011_IMSC_FEIM (1 << 7) +#define UART_PL011_IMSC_RTIM (1 << 6) +#define UART_PL011_IMSC_TXIM (1 << 5) +#define UART_PL011_IMSC_RXIM (1 << 4) +#define UART_PL011_IMSC_DSRMIM (1 << 3) +#define UART_PL011_IMSC_DCDMIM (1 << 2) +#define UART_PL011_IMSC_CTSMIM (1 << 1) +#define UART_PL011_IMSC_RIMIM (1 << 0) + +uint8_t arm_uart_getc(void); +void arm_uart_putc(uint8_t ch); +void arm_uart_init(void); + +#endif /* __ARM_UART_H_ */ diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.s new file mode 100644 index 0000000..b211585 --- /dev/null +++ b/ports/arm7a/atomport-asm.s @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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. + */ + +.section .text + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +.globl archContextSwitch +archContextSwitch: + bx lr + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +.globl archFirstThreadRestore +archFirstThreadRestore: + bx lr + diff --git a/ports/arm7a/atomport-private.h b/ports/arm7a/atomport-private.h new file mode 100644 index 0000000..a6e8aad --- /dev/null +++ b/ports/arm7a/atomport-private.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_PRIVATE_H_ +#define __ATOMPORT_PRIVATE_H_ + +#define CPSR_MODE_MASK 0x0000001f +#define CPSR_MODE_USER 0x00000010 +#define CPSR_MODE_FIQ 0x00000011 +#define CPSR_MODE_IRQ 0x00000012 +#define CPSR_MODE_SUPERVISOR 0x00000013 +#define CPSR_MODE_ABORT 0x00000017 +#define CPSR_MODE_UNDEFINED 0x0000001b +#define CPSR_MODE_SYSTEM 0x0000001f + +#define CPSR_THUMB_ENABLED (1 << 5) +#define CPSR_FIQ_DISABLED (1 << 6) +#define CPSR_IRQ_DISABLED (1 << 7) +#define CPSR_ASYNC_ABORT_DISABLED (1 << 8) +#define CPSR_BE_ENABLED (1 << 9) + +#define CPSR_COND_OVERFLOW (1 << 28) +#define CPSR_COND_CARRY (1 << 29) +#define CPSR_COND_ZERO (1 << 30) +#define CPSR_COND_NEGATIVE (1 << 31) + +#endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/arm7a/atomport-tests.h b/ports/arm7a/atomport-tests.h new file mode 100644 index 0000000..d76e27d --- /dev/null +++ b/ports/arm7a/atomport-tests.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H +#define __ATOM_PORT_TESTS_H + +/* Include Atomthreads kernel API */ +#include "atom.h" + +/* Logger macro for viewing test results */ +/* FIXME: Add uart out routine once uart is supported */ +#define ATOMLOG printk +#define _STR + +/* Default thread stack size (in bytes) */ +#define TEST_THREAD_STACK_SIZE 8192 + +/* Uncomment to enable logging of stack usage to UART */ +/* #define TESTS_LOG_STACK_USAGE */ + +#endif /* __ATOM_PORT_TESTS_H */ + diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c new file mode 100644 index 0000000..c2019d8 --- /dev/null +++ b/ports/arm7a/atomport.c @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +/** + * This function initialises each thread's stack during creation, before the + * thread is first run. New threads are scheduled in using the same + * context-switch function used for threads which were previously scheduled + * out, therefore this function should set up a stack context which looks + * much like a thread which has been scheduled out and had its context saved. + * We fill part of the stack with those registers which are involved in the + * context switch, including appropriate stack or register contents to cause + * the thread to branch to its entry point function when it is scheduled in. + * + * Interrupts should also be enabled whenever a thread is restored, hence + * ports may wish to explicitly include the interrupt-enable register here + * which will be restored when the thread is scheduled in. Other methods + * can be used to enable interrupts, however, without explicitly storing + * it in the thread's context. + */ +void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, + void (*entry_point)(UINT32), + UINT32 entry_param) +{ + +} + diff --git a/ports/arm7a/atomport.h b/ports/arm7a/atomport.h new file mode 100644 index 0000000..73b19e3 --- /dev/null +++ b/ports/arm7a/atomport.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H +#define __ATOM_PORT_H + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 100 + +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; + +typedef unsigned int irq_flags_t; +typedef unsigned int virtual_addr_t; +typedef unsigned int virtual_size_t; +typedef unsigned int physical_addr_t; +typedef unsigned int physical_size_t; +typedef unsigned int clock_freq_t; +typedef unsigned long long jiffies_t; + +#define UINT32 uint32_t +#define STACK_ALIGN_SIZE sizeof(uint32_t) +#define NULL ((void *)(0)) + +/** + * Architecture-specific types. + * Most of these are available from stdint.h on this platform, which is + * included above. + */ +#define POINTER void * + +struct pt_regs { + uint32_t cpsr; // Current Program Status + uint32_t gpr[13]; // R0 - R12 + uint32_t sp; + uint32_t lr; + uint32_t pc; +} __attribute ((packed)) ; +typedef struct pt_regs pt_regs_t; + +#include + +extern uint32_t at_preempt_count; + +#if 0 +/* Critical region protection */ +#define CRITICAL_STORE uint32_t status_reg +#define CRITICAL_START() \ + do { \ + extern uint32_t at_preempt_count; \ + at_preempt_count++; \ + }while(0); + +#define CRITICAL_END() \ + do { \ + extern uint32_t at_preempt_count; \ + if (at_preempt_count == 0) { \ + printk("BUG: Preempt count is zero!\n"); \ + for(;;); \ + } \ + at_preempt_count--; \ + \ + if (at_preempt_count == 0) { \ + if (atomCurrentContext()) { \ + } \ + } \ + \ + }while(0); +#else +#define CRITICAL_STORE +#define CRITICAL_START() +#define CRITICAL_END() +#endif + +/* Uncomment to enable stack-checking */ +/* #define ATOM_STACK_CHECKING */ + +#endif /* __ATOM_PORT_H */ diff --git a/ports/arm7a/linker.ld b/ports/arm7a/linker.ld new file mode 100755 index 0000000..8af91e3 --- /dev/null +++ b/ports/arm7a/linker.ld @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH("arm") +ENTRY(_start_vect) + +SECTIONS +{ + . = 0x100000; + + .text : + { + *(.expvect) + *(.text) + . = ALIGN(4); + _etext = .; + } + + .data : + { + *(.data) + . = ALIGN(4); + _edata = .; + } + + .bss : + { + *(.bss) + . = ALIGN(4); + _ebss = .; + } + + .rodata : + { + *(.rodata .rodata.*) + . = ALIGN(4); + _erodata = .; + } + + .cmdbtl : + { + PROVIDE(_cmdtbl_start = .); + *(.cmdtbl) + . = ALIGN(4); + PROVIDE(_cmdtbl_end = .); + } + + .modtbl : + { + PROVIDE(_modtbl_start = .); + *(.modtbl) + . = ALIGN(4); + PROVIDE(_modtbl_end = .); + } + + .svc_stack : + { + PROVIDE(_svc_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_svc_stack_end = .); + } + + .mon_stack : + { + PROVIDE(_mon_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_mon_stack_end = .); + } + + .abt_stack : + { + PROVIDE(_abt_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_abt_stack_end = .); + } + + .und_stack : + { + PROVIDE(_und_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_und_stack_end = .); + } + + .irq_stack : + { + PROVIDE(_irq_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_irq_stack_end = .); + } + + .fiq_stack : + { + PROVIDE(_fiq_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_fiq_stack_end = .); + } + + .usr_stack : + { + PROVIDE(_usr_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_usr_stack_end = .); + } +} diff --git a/ports/arm7a/printk.c b/ports/arm7a/printk.c new file mode 100644 index 0000000..99d137f --- /dev/null +++ b/ports/arm7a/printk.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include +#include +#include + +static int8_t buf[2048]; + +/* Uses the above routine to output a string... */ +void puts(const uint8_t *text) +{ + int32_t i; + + for (i = 0; i < strlen((const int8_t *)text); i++) { + arm_uart_putc(text[i]); + } +} + +void printk(const char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = vsprintf(buf, (const int8_t *)format, args); + va_end(args); + + puts((const uint8_t *)buf); +} + diff --git a/ports/arm7a/printk.h b/ports/arm7a/printk.h new file mode 100644 index 0000000..bd1b192 --- /dev/null +++ b/ports/arm7a/printk.h @@ -0,0 +1,42 @@ +/* + * This file is part of Freax kernel. + * + * Copyright (c) Himanshu Chauhan 2009-10. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H +#define _PRINTK_H + +#include "atomport.h" + +extern void putch (uint8_t ch); +extern void puts (const uint8_t *text); +extern void printk (const char*format, ...); + +#endif diff --git a/ports/arm7a/stdarg.h b/ports/arm7a/stdarg.h new file mode 100755 index 0000000..fd79ec0 --- /dev/null +++ b/ports/arm7a/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/ports/arm7a/string.c b/ports/arm7a/string.c new file mode 100644 index 0000000..b99b529 --- /dev/null +++ b/ports/arm7a/string.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +void *memcpy(void *dest, const void *src, size_t count) +{ + const int8_t *sp = (const int8_t *)src; + int8_t *dp = (int8_t *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, int8_t val, size_t count) +{ + int8_t *temp = (int8_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) +{ + uint16_t *temp = (uint16_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +size_t strlen(const int8_t *str) +{ + size_t retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} diff --git a/ports/arm7a/string.h b/ports/arm7a/string.h new file mode 100644 index 0000000..bbccc25 --- /dev/null +++ b/ports/arm7a/string.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H +#define __STRING_H + +#include + +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *dest, int8_t val, size_t count); +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); +size_t strlen(const int8_t *str); + +#endif /* __STRING_H */ + diff --git a/ports/arm7a/system.h b/ports/arm7a/system.h new file mode 100644 index 0000000..b8c25ad --- /dev/null +++ b/ports/arm7a/system.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H +#define _SYSTEM_H + +#include +#include + +extern const uint8_t *kernel_name; +extern const uint8_t *kernel_version; +extern const uint8_t *kernel_bdate; +extern const uint8_t *kernel_btime; + +extern void *memcpy (void *dest, const void *src, size_t count); +extern void *memset (void *dest, int8_t val, size_t count); +extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); +extern size_t strlen (const int8_t *str); +extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); +extern void init_console (void); +extern int32_t arch_init (void); +extern uint8_t ioreadb (void *addr); +extern void iowriteb (void *addr, uint8_t data); + +#endif /* _SYSTEM_H */ diff --git a/ports/arm7a/vsprintf.c b/ports/arm7a/vsprintf.c new file mode 100644 index 0000000..c8819fd --- /dev/null +++ b/ports/arm7a/vsprintf.c @@ -0,0 +1,244 @@ +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + * and Himanshu Fucked it up further :)) + */ + +#include +#include +#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const int8_t **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +/*#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; })*/ + +static uint32_t do_div (int32_t *n, int32_t base) +{ + uint32_t remainder = *n % base; + *n /= base; + return remainder; +} + +static int8_t * number(int8_t * str, int num, int32_t base, + int32_t size, int32_t precision, int32_t type) +{ + int8_t c,sign,tmp[36]; + const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int32_t i; + + if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; + if (type & LEFT) type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type & SIGN && num < 0) { + sign = '-'; + num = -num; + } else + sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); + if (sign) size--; + + if (type & SPECIAL) { + if (base == 16) { + size -= 2; + } else if (base == 8) { + size--; + } + } + + i = 0; + if (num == 0) + tmp[i++] = '0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while(size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) { + *str++ = '0'; + } else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while(size-- > 0) + *str++ = c; + while(i < precision--) + *str++ = '0'; + while(i-- > 0) + *str++ = tmp[i]; + while(size-- > 0) + *str++ = ' '; + return str; +} + +int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args) +{ + int32_t len; + int32_t i; + int8_t * str; + int8_t *s; + int32_t *ip; + + int32_t flags; /* flags to number() */ + + int32_t field_width; /* width of output field */ + int32_t precision; /* min. # of digits for integers; max + number of chars for from string */ + int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, int8_t *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int32_t *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} From b213428c2404a059de77feb3792a87bc5eed1f3e Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Mon, 4 Jul 2011 20:09:40 +0530 Subject: [PATCH 45/76] Fixed ARM7a makefile. --- ports/arm7a/Makefile | 61 ++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 33 deletions(-) diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile index db3f78d..816ebe8 100644 --- a/ports/arm7a/Makefile +++ b/ports/arm7a/Makefile @@ -9,8 +9,11 @@ # make program app=appname # Location of build tools and atomthreads sources -KERNEL_DIR=../../kernel -TESTS_DIR=../../tests +kernel_dir=../../kernel +tests_dir=../../tests + +# Directory for built objects +build_dir=build CPU=cortex-a8 BOARD=pb-a8 @@ -41,9 +44,6 @@ endif # must disable stack-checking to run all of the automated tests. #STACK_CHECK=true -# Directory for built objects -BUILD_DIR=build - # Port/application object files APP_OBJECTS = arm_irq.o APP_OBJECTS += arm_gic.o @@ -66,19 +66,17 @@ KERNEL_OBJECTS += atomqueue.o # Collection of built objects (excluding test applications) ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) -BUILT_OBJECTS = $(patsubst %,$(BUILD_DIR)/%,$(ALL_OBJECTS)) +BUILT_OBJECTS = $(patsubst %,$(build_dir)/%,$(ALL_OBJECTS)) # Test object files (dealt with separately as only one per application build) -TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(TESTS_DIR)/*.c))) +TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) -# Target application filenames (.elf and .hex) for each test object +# Target application filenames .elf for each test object TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) -TEST_HEXS = $(patsubst %.o,%.hex,$(TEST_OBJECTS)) # Search build/output directory for dependencies -vpath %.o ./$(BUILD_DIR) -vpath %.elf ./$(BUILD_DIR) -vpath %.hex ./$(BUILD_DIR) +vpath %.o ./$(build_dir) +vpath %.elf ./$(build_dir) # GCC flags CFLAGS= -g \ @@ -103,54 +101,51 @@ endif ################# # All tests -all: $(BUILD_DIR) $(TEST_HEXS) Makefile - -# Make build/output directory -$(BUILD_DIR): - mkdir $(BUILD_DIR) - -# Test HEX files (one application build for each test) -$(TEST_HEXS): %.hex: %.elf - $(if $(V), @echo " (HEX) $(subst $(build_dir)/,,$@)") - $(V)$(OBJCOPY) -j .text -j .data -O ihex $(BUILD_DIR)/$< $(BUILD_DIR)/$@ +all: $(TEST_ELFS) Makefile # Test ELF files (one application build for each test) $(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) + $(V)mkdir -p `dirname $(build_dir)/$@` $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(BUILD_DIR)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(BUILD_DIR)/$@ -Wl -T linker.ld + $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(build_dir)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(build_dir)/$@ -Wl -T linker.ld # Kernel objects builder -$(KERNEL_OBJECTS): %.o: $(KERNEL_DIR)/%.c +$(KERNEL_OBJECTS): %.o: $(kernel_dir)/%.c + $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) # Test objects builder -$(TEST_OBJECTS): %.o: $(TESTS_DIR)/%.c +$(TEST_OBJECTS): %.o: $(tests_dir)/%.c + $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) # Application C objects builder $(APP_OBJECTS): %.o: ./%.c + $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) $< -o $(build_dir)/$(notdir $@) # Application asm objects builder $(APP_ASM_OBJECTS): %.o: ./%.s + $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(KERNEL_DIR) $< -o $(BUILD_DIR)/$(notdir $@) + $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) # .lst file builder %.lst: %.c + $(V)mkdir -p `dirname $@` $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -I. -I$(KERNEL_DIR) -I$(TESTS_DIR) -Wa,-al $< > $@ + $(V)$(CC) $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) -Wa,-al $< > $@ # Clean clean: - $(V)rm -f *.o *.elf *.map *.hex *.bin *.lst + $(V)rm -f *.o *.elf *.map *.bin *.lst rm -rf doxygen-kernel rm -rf doxygen-avr - rm -rf build + rm -rf $(build_dir) doxygen: - doxygen $(KERNEL_DIR)/Doxyfile + doxygen $(kernel_dir)/Doxyfile doxygen ./Doxyfile From 2df02ed0ad6b9a6002cc114e97d18844ed8e4c20 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Tue, 5 Jul 2011 14:27:30 +0530 Subject: [PATCH 46/76] Fixed CRITICAL section macros. Signed-off-by: Anup Patel --- ports/arm7a/arm_irq.c | 55 +++++++++++++++++++++++++++++++++++++++++ ports/arm7a/arm_irq.h | 2 ++ ports/arm7a/arm_main.c | 2 -- ports/arm7a/arm_timer.c | 6 ----- ports/arm7a/atomport.h | 34 +++---------------------- 5 files changed, 61 insertions(+), 38 deletions(-) diff --git a/ports/arm7a/arm_irq.c b/ports/arm7a/arm_irq.c index 153bad2..1aec38c 100644 --- a/ports/arm7a/arm_irq.c +++ b/ports/arm7a/arm_irq.c @@ -36,22 +36,47 @@ arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; void do_undefined_instruction(pt_regs_t *regs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_software_interrupt(pt_regs_t *regs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_prefetch_abort(pt_regs_t *regs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_data_abort(pt_regs_t *regs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_not_used(pt_regs_t *regs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_irq(pt_regs_t *uregs) @@ -59,6 +84,9 @@ void do_irq(pt_regs_t *uregs) int rc = 0; int irq = arm_gic_active_irq(0); + /* Call the interrupt entry routine */ + atomIntEnter(); + if (-1 < irq) { if (irq_hndls[irq]) { rc = irq_hndls[irq](irq, uregs); @@ -71,10 +99,18 @@ void do_irq(pt_regs_t *uregs) while (1); } } + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void do_fiq(pt_regs_t *uregs) { + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); } void arm_irq_setup(void) @@ -149,3 +185,22 @@ void arm_irq_disable(void) __asm( "cpsid if" ); } +irq_flags_t arm_irq_save(void) +{ + unsigned long retval; + + asm volatile (" mrs %0, cpsr\n\t" " cpsid i" /* Syntax CPSID {, #} + * Note: This instruction is supported + * from ARM6 and above + */ + :"=r" (retval)::"memory", "cc"); + + return retval; +} + +void arm_irq_restore(irq_flags_t flags) +{ + asm volatile (" msr cpsr_c, %0"::"r" (flags) + :"memory", "cc"); +} + diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h index bad336d..1f0431e 100644 --- a/ports/arm7a/arm_irq.h +++ b/ports/arm7a/arm_irq.h @@ -51,5 +51,7 @@ void arm_irq_setup(void); void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); void arm_irq_enable(void); void arm_irq_disable(void); +irq_flags_t arm_irq_save(void); +void arm_irq_restore(irq_flags_t flags); #endif /* __ARM_IRQ_H */ diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index 7cfd526..cb324f8 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -177,8 +177,6 @@ int main ( void ) { arm_irq_setup(); - arm_irq_enable(); - arm_timer_init(1000, 1); arm_uart_init(); diff --git a/ports/arm7a/arm_timer.c b/ports/arm7a/arm_timer.c index 8a64676..ed5b359 100644 --- a/ports/arm7a/arm_timer.c +++ b/ports/arm7a/arm_timer.c @@ -62,15 +62,9 @@ void arm_timer_clearirq(void) int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) { - /* Call the interrupt entry routine */ - atomIntEnter(); - /* Call the OS system tick handler */ atomTimerTick(); - /* Call the interrupt exit routine */ - atomIntExit(TRUE); - arm_timer_clearirq(); return 0; diff --git a/ports/arm7a/atomport.h b/ports/arm7a/atomport.h index 73b19e3..debf68a 100644 --- a/ports/arm7a/atomport.h +++ b/ports/arm7a/atomport.h @@ -71,38 +71,12 @@ struct pt_regs { typedef struct pt_regs pt_regs_t; #include +#include -extern uint32_t at_preempt_count; - -#if 0 /* Critical region protection */ -#define CRITICAL_STORE uint32_t status_reg -#define CRITICAL_START() \ - do { \ - extern uint32_t at_preempt_count; \ - at_preempt_count++; \ - }while(0); - -#define CRITICAL_END() \ - do { \ - extern uint32_t at_preempt_count; \ - if (at_preempt_count == 0) { \ - printk("BUG: Preempt count is zero!\n"); \ - for(;;); \ - } \ - at_preempt_count--; \ - \ - if (at_preempt_count == 0) { \ - if (atomCurrentContext()) { \ - } \ - } \ - \ - }while(0); -#else -#define CRITICAL_STORE -#define CRITICAL_START() -#define CRITICAL_END() -#endif +#define CRITICAL_STORE irq_flags_t status_flags +#define CRITICAL_START() status_flags = arm_irq_save(); +#define CRITICAL_END() arm_irq_restore(status_flags); /* Uncomment to enable stack-checking */ /* #define ATOM_STACK_CHECKING */ From 0ee1eb55c53d8d39816b34e71e3e85801d18803b Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Tue, 5 Jul 2011 17:03:21 +0530 Subject: [PATCH 47/76] Got one thread working. Signed-off-by: Anup Patel --- ports/arm7a/arm_asm_macro.h | 123 ++++++++++++++++++ .../{atomport-private.h => arm_defines.h} | 59 +++++---- ports/arm7a/arm_entry.s | 109 ++++------------ ports/arm7a/arm_irq.h | 2 +- ports/arm7a/arm_main.c | 1 - ports/arm7a/atomport-asm.s | 21 ++- ports/arm7a/atomport.c | 14 +- ports/arm7a/linker.ld | 70 +--------- 8 files changed, 221 insertions(+), 178 deletions(-) create mode 100644 ports/arm7a/arm_asm_macro.h rename ports/arm7a/{atomport-private.h => arm_defines.h} (53%) diff --git a/ports/arm7a/arm_asm_macro.h b/ports/arm7a/arm_asm_macro.h new file mode 100644 index 0000000..4d833b3 --- /dev/null +++ b/ports/arm7a/arm_asm_macro.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_ASM_MACRO_H__ +#define __ARM_ASM_MACRO_H__ + +#include + +#ifdef __ASSEMBLY__ + +.macro SET_CURRENT_FLAGS flags, treg + mrs \treg, cpsr + orr \treg, \treg, #(\flags) + msr cpsr, \treg +.endm + +.macro SET_CURRENT_MODE mode + cps #(\mode) +.endm + +.macro SET_CURRENT_STACK new_stack + ldr sp, \new_stack +.endm + +.macro START_EXCEPTION_HANDLER irqname, lroffset + .align 5 +\irqname: + sub lr, lr, #\lroffset +.endm + +/* Save User Registers */ +.macro PUSH_USER_REGS + str lr, [sp, #-4]!; /* Push the return address */ + sub sp, sp, #(4*15); /* Adjust the stack pointer */ + stmia sp, {r0-r12}; /* Push user mode registers */ + add r0, sp, #(4*13); /* Adjust the stack pointer */ + stmia r0, {r13-r14}^; /* Push user mode registers */ + mov r0, r0; /* NOP for previous inst */ + mrs r0, spsr_all; /* Put the SPSR on the stack */ + str r0, [sp, #-4]! +.endm + +/* If came from priviledged mode then push banked registers */ +.macro PUSH_BANKED_REGS skip_lable + mov r4, r0 + and r0, r0, #CPSR_MODE_MASK + cmp r0, #CPSR_MODE_USER + beq \skip_lable + add r1, sp, #(4*14) + mrs r5, cpsr + orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr, r4 + str sp, [r1, #0] + str lr, [r1, #4] + msr cpsr, r5 + \skip_lable: +.endm + +/* Call C function to handle exception */ +.macro CALL_EXCEPTION_CFUNC cfunc + mov r0, sp + bl \cfunc +.endm + +/* If going back to priviledged mode then pull banked registers */ +.macro PULL_BANKED_REGS skip_lable + ldr r0, [sp, #0] + mov r4, r0 + and r0, r0, #CPSR_MODE_MASK + cmp r0, #CPSR_MODE_USER + beq \skip_lable + add r1, sp, #(4*14) + mrs r5, cpsr + orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr, r4 + ldr sp, [r1, #0] + ldr lr, [r1, #4] + msr cpsr, r5 + \skip_lable: +.endm + +/* Restore User Registers */ +.macro PULL_USER_REGS + ldr r0, [sp], #0x0004; /* Get SPSR from stack */ + msr spsr_all, r0; + ldmia sp, {r0-r14}^; /* Restore registers (user) */ + mov r0, r0; /* NOP for previous isnt */ + add sp, sp, #(4*15); /* Adjust the stack pointer */ + ldr lr, [sp], #0x0004 /* Pull return address */ +.endm + +.macro END_EXCEPTION_HANDLER + movs pc, lr +.endm + +#endif + +#endif diff --git a/ports/arm7a/atomport-private.h b/ports/arm7a/arm_defines.h similarity index 53% rename from ports/arm7a/atomport-private.h rename to ports/arm7a/arm_defines.h index a6e8aad..8de737c 100644 --- a/ports/arm7a/atomport-private.h +++ b/ports/arm7a/arm_defines.h @@ -27,27 +27,42 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef __ATOMPORT_PRIVATE_H_ -#define __ATOMPORT_PRIVATE_H_ +#ifndef __ARM_DEFINES_H_ +#define __ARM_DEFINES_H_ -#define CPSR_MODE_MASK 0x0000001f -#define CPSR_MODE_USER 0x00000010 -#define CPSR_MODE_FIQ 0x00000011 -#define CPSR_MODE_IRQ 0x00000012 -#define CPSR_MODE_SUPERVISOR 0x00000013 -#define CPSR_MODE_ABORT 0x00000017 -#define CPSR_MODE_UNDEFINED 0x0000001b -#define CPSR_MODE_SYSTEM 0x0000001f +#define CPSR_VALIDBITS_MASK 0xFF0FFFFF +#define CPSR_USERBITS_MASK 0xFFFFFC00 +#define CPSR_USERBITS_SHIFT 10 +#define CPSR_PRIVBITS_MASK 0x000003FF +#define CPSR_PRIVBITS_SHIFT 0 +#define CPSR_MODE_MASK 0x0000001f +#define CPSR_MODE_USER 0x00000010 +#define CPSR_MODE_FIQ 0x00000011 +#define CPSR_MODE_IRQ 0x00000012 +#define CPSR_MODE_SUPERVISOR 0x00000013 +#define CPSR_MODE_MONITOR 0x00000016 +#define CPSR_MODE_ABORT 0x00000017 +#define CPSR_MODE_UNDEFINED 0x0000001b +#define CPSR_MODE_SYSTEM 0x0000001f +#define CPSR_THUMB_ENABLED (1 << 5) +#define CPSR_FIQ_DISABLED (1 << 6) +#define CPSR_IRQ_DISABLED (1 << 7) +#define CPSR_ASYNC_ABORT_DISABLED (1 << 8) +#define CPSR_BE_ENABLED (1 << 9) +#define CPSR_IT2_MASK 0x0000FC00 +#define CPSR_IT2_SHIFT 10 +#define CPSR_GE_MASK 0x000F0000 +#define CPSR_GE_SHIFT 16 +#define CPSR_JAZZLE_ENABLED (1 << 24) +#define CPSR_IT1_MASK 0x06000000 +#define CPSR_IT1_SHIFT 25 +#define CPSR_COND_OVERFLOW_MASK (1 << 28) +#define CPSR_COND_OVERFLOW_SHIFT 28 +#define CPSR_COND_CARRY_MASK (1 << 29) +#define CPSR_COND_CARRY_SHIFT 29 +#define CPSR_COND_ZERO_MASK (1 << 30) +#define CPSR_COND_ZERO_SHIFT 30 +#define CPSR_COND_NEGATIVE_MASK (1 << 31) +#define CPSR_COND_NEGATIVE_SHIFT 31 -#define CPSR_THUMB_ENABLED (1 << 5) -#define CPSR_FIQ_DISABLED (1 << 6) -#define CPSR_IRQ_DISABLED (1 << 7) -#define CPSR_ASYNC_ABORT_DISABLED (1 << 8) -#define CPSR_BE_ENABLED (1 << 9) - -#define CPSR_COND_OVERFLOW (1 << 28) -#define CPSR_COND_CARRY (1 << 29) -#define CPSR_COND_ZERO (1 << 30) -#define CPSR_COND_NEGATIVE (1 << 31) - -#endif /* __ATOMPORT_PRIVATE_H_ */ +#endif /* __ARM_DEFINES_H_ */ diff --git a/ports/arm7a/arm_entry.s b/ports/arm7a/arm_entry.s index c19d651..9f21d94 100644 --- a/ports/arm7a/arm_entry.s +++ b/ports/arm7a/arm_entry.s @@ -27,71 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include - -.macro SET_CURRENT_FLAGS flags, treg - mrs \treg, cpsr - orr \treg, \treg, #(\flags) - msr cpsr, \treg -.endm - -.macro SET_CURRENT_MODE mode - cps #(\mode) -.endm - -.macro SET_CURRENT_STACK new_stack - ldr sp, \new_stack -.endm - -.macro START_EXCEPTION_HANDLER irqname, lroffset - .align 5 -\irqname: - sub lr, lr, #\lroffset -.endm - -/* Save User Registers */ -.macro PUSH_USER_REGS - str lr, [sp, #-4]!; /* Push the return address */ - sub sp, sp, #(4*15); /* Adjust the stack pointer */ - stmia sp, {r0-r12}; /* Push user mode registers */ - add r0, sp, #(4*13); /* Adjust the stack pointer */ - stmia r0, {r13-r14}^; /* Push user mode registers */ - mov r0, r0; /* NOP for previous inst */ - mrs r0, spsr_all; /* Put the SPSR on the stack */ - str r0, [sp, #-4]! -.endm - -/* Save User Registers in FIQ */ -.macro PUSH_FIQUSER_REGS - str lr, [sp, #-4]!; /* Push the return address */ - sub sp, sp, #(4*15); /* Adjust the stack pointer */ - stmia sp, {r0-r7}; /* Push user mode registers */ - add r0, sp, #(4*8); /* Adjust the stack pointer */ - stmia r0, {r8-r14}^; /* Push user mode registers */ - mov r0, r0; /* NOP for previous inst */ - mrs r0, spsr_all; /* Put the SPSR on the stack */ - str r0, [sp, #-4]! -.endm - -/* Call C function to handle exception */ -.macro CALL_EXCEPTION_CFUNC cfunc - mov r0, sp - bl \cfunc -.endm - -/* Restore User Registers */ -.macro PULL_USER_REGS - ldr r0, [sp], #0x0004; /* Get SPSR from stack */ - msr spsr_all, r0; - ldmia sp, {r0-r14}^; /* Restore registers (user) */ - mov r0, r0; /* NOP for previous isnt */ - add sp, sp, #(4*15); /* Adjust the stack pointer */ - ldr lr, [sp], #0x0004 /* Pull return address */ -.endm - -.macro END_EXCEPTION_HANDLER - movs pc, lr -.endm +#include .section .expvect, "ax", %progbits .globl _start_vect @@ -123,18 +59,8 @@ __fiq: .global _end_vect _end_vect: -__svc_stack_end: - .word _svc_stack_end -__und_stack_end: - .word _und_stack_end -__abt_stack_end: - .word _abt_stack_end -__irq_stack_end: - .word _irq_stack_end -__fiq_stack_end: - .word _fiq_stack_end -__usr_stack_end: - .word _usr_stack_end +__initial_stack_end: + .word _initial_stack_end .globl _reset _reset: @@ -144,69 +70,82 @@ _reset: cpsid if /* Set Supervisor Mode Stack */ SET_CURRENT_MODE CPSR_MODE_SUPERVISOR - SET_CURRENT_STACK __svc_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set Undefined Mode Stack */ SET_CURRENT_MODE CPSR_MODE_UNDEFINED - SET_CURRENT_STACK __und_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set Abort Mode Stack */ SET_CURRENT_MODE CPSR_MODE_ABORT - SET_CURRENT_STACK __abt_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set IRQ Mode Stack */ SET_CURRENT_MODE CPSR_MODE_IRQ - SET_CURRENT_STACK __irq_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set FIQ Mode Stack */ SET_CURRENT_MODE CPSR_MODE_FIQ - SET_CURRENT_STACK __fiq_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set System Mode Stack */ SET_CURRENT_MODE CPSR_MODE_SYSTEM - SET_CURRENT_STACK __usr_stack_end + SET_CURRENT_STACK __initial_stack_end /* Set to Supervisor Mode */ SET_CURRENT_MODE CPSR_MODE_SUPERVISOR /* Call main function */ bl main /* We should never reach here */ b . - START_EXCEPTION_HANDLER _undefined_instruction, 4 PUSH_USER_REGS + PUSH_BANKED_REGS _undefined_instruction_bankpush_skip CALL_EXCEPTION_CFUNC do_undefined_instruction + PULL_BANKED_REGS _undefined_instruction_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _software_interrupt, 4 PUSH_USER_REGS + PUSH_BANKED_REGS _software_interrupt_bankpush_skip CALL_EXCEPTION_CFUNC do_software_interrupt + PULL_BANKED_REGS _software_interrupt_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _prefetch_abort, 4 PUSH_USER_REGS + PUSH_BANKED_REGS _prefetch_abort_bankpush_skip CALL_EXCEPTION_CFUNC do_prefetch_abort + PULL_BANKED_REGS _prefetch_abort_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _data_abort, 8 PUSH_USER_REGS + PUSH_BANKED_REGS _data_abort_bankpush_skip CALL_EXCEPTION_CFUNC do_data_abort + PULL_BANKED_REGS _data_abort_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _not_used, 4 PUSH_USER_REGS + PUSH_BANKED_REGS _not_used_bankpush_skip CALL_EXCEPTION_CFUNC do_not_used + PULL_BANKED_REGS _not_used_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _irq, 4 PUSH_USER_REGS + PUSH_BANKED_REGS _irq_bankpush_skip CALL_EXCEPTION_CFUNC do_irq + PULL_BANKED_REGS _irq_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER START_EXCEPTION_HANDLER _fiq, 4 - PUSH_FIQUSER_REGS + PUSH_USER_REGS + PUSH_BANKED_REGS _fiq_bankpush_skip CALL_EXCEPTION_CFUNC do_fiq + PULL_BANKED_REGS _fiq_bankpull_skip PULL_USER_REGS END_EXCEPTION_HANDLER diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h index 1f0431e..89f963f 100644 --- a/ports/arm7a/arm_irq.h +++ b/ports/arm7a/arm_irq.h @@ -31,7 +31,7 @@ #define __ARM_IRQ_H #include -#include +#include typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index cb324f8..4e60eba 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -28,7 +28,6 @@ */ #include -#include #include #include #include diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.s index b211585..f1d37f2 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.s @@ -27,6 +27,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + .section .text /** @@ -54,5 +56,22 @@ archContextSwitch: */ .globl archFirstThreadRestore archFirstThreadRestore: - bx lr + ldr r0, [r0] + mov sp, r0 + mrs r1, cpsr + SET_CURRENT_MODE CPSR_MODE_UNDEFINED + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_ABORT + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_IRQ + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_FIQ + mov sp, r0 + msr cpsr, r1 + sub sp, sp, #(4 * 17) + ldr r0, [sp], #0x0004; /* Get CPSR from stack */ + msr spsr_all, r0; + ldmia sp, {r0-r14}; /* Restore registers */ + mov r0, r0; /* NOP for previous isnt */ + movs pc, lr diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index c2019d8..e4c7ffa 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -29,9 +29,9 @@ */ #include -#include #include #include +#include /** * This function initialises each thread's stack during creation, before the @@ -53,6 +53,18 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(UINT32), UINT32 entry_param) { + int i; + pt_regs_t *regs = (pt_regs_t *)((uint32_t)stack_top - sizeof(pt_regs_t)); + tcb_ptr->sp_save_ptr = stack_top; + regs->cpsr = CPSR_COND_ZERO_MASK | + CPSR_ASYNC_ABORT_DISABLED | CPSR_MODE_SUPERVISOR; + regs->gpr[0] = entry_param; + for (i = 1; i < 13; i++) { + regs->gpr[i] = 0x0; + } + regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 2048; + regs->lr = (uint32_t)entry_point; + regs->pc = (uint32_t)entry_point; } diff --git a/ports/arm7a/linker.ld b/ports/arm7a/linker.ld index 8af91e3..f91ed6e 100755 --- a/ports/arm7a/linker.ld +++ b/ports/arm7a/linker.ld @@ -64,75 +64,11 @@ SECTIONS _erodata = .; } - .cmdbtl : - { - PROVIDE(_cmdtbl_start = .); - *(.cmdtbl) - . = ALIGN(4); - PROVIDE(_cmdtbl_end = .); - } - - .modtbl : - { - PROVIDE(_modtbl_start = .); - *(.modtbl) - . = ALIGN(4); - PROVIDE(_modtbl_end = .); - } - - .svc_stack : + .initial_stack : { - PROVIDE(_svc_stack_start = .); + PROVIDE(_initial_stack_start = .); . = . + 4096; . = ALIGN(4); - PROVIDE(_svc_stack_end = .); - } - - .mon_stack : - { - PROVIDE(_mon_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_mon_stack_end = .); - } - - .abt_stack : - { - PROVIDE(_abt_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_abt_stack_end = .); - } - - .und_stack : - { - PROVIDE(_und_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_und_stack_end = .); - } - - .irq_stack : - { - PROVIDE(_irq_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_irq_stack_end = .); - } - - .fiq_stack : - { - PROVIDE(_fiq_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_fiq_stack_end = .); - } - - .usr_stack : - { - PROVIDE(_usr_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_usr_stack_end = .); + PROVIDE(_initial_stack_end = .); } } From a4a35ddf86b575450bb0b9ed67ae0be2fe3bb793 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Tue, 5 Jul 2011 17:35:41 +0530 Subject: [PATCH 48/76] Minor refactoring of code. Signed-off-by: Anup Patel --- ports/arm7a/atomport-asm.s | 36 +++++++++++++----------------- ports/arm7a/atomport.c | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+), 21 deletions(-) diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.s index f1d37f2..ee6c1bd 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.s @@ -32,32 +32,25 @@ .section .text /** - * Function that performs the contextSwitch. Whether its a voluntary release - * of CPU by thread or a pre-emption, under both conditions this function is - * called. The signature is as follows: - * - * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + * int archSetJumpLowLevel(pt_regs_t *regs) */ -.globl archContextSwitch -archContextSwitch: +.globl archSetJumpLowLevel +archSetJumpLowLevel: bx lr /** - * archFirstThreadRestore(ATOM_TCB *new_tcb) - * - * This function is responsible for restoring and starting the first - * thread the OS runs. It expects to find the thread context exactly - * as it would be if a context save had previously taken place on it. - * The only real difference between this and the archContextSwitch() - * routine is that there is no previous thread for which context must - * be saved. - * - * The final action this function must do is to restore interrupts. + * void archLongJumpLowLevel(pt_regs_t *regs) */ -.globl archFirstThreadRestore -archFirstThreadRestore: - ldr r0, [r0] - mov sp, r0 +.globl archLongJumpLowLevel +archLongJumpLowLevel: + bx lr + +/** + * void archFirstThreadRestoreLowLevel(pt_regs_t *regs) + */ +.globl archFirstThreadRestoreLowLevel +archFirstThreadRestoreLowLevel: + add r0, r0, #(4 * 17) mrs r1, cpsr SET_CURRENT_MODE CPSR_MODE_UNDEFINED mov sp, r0 @@ -68,6 +61,7 @@ archFirstThreadRestore: SET_CURRENT_MODE CPSR_MODE_FIQ mov sp, r0 msr cpsr, r1 + mov sp, r0 sub sp, sp, #(4 * 17) ldr r0, [sp], #0x0004; /* Get CPSR from stack */ msr spsr_all, r0; diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index e4c7ffa..67496ce 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -68,3 +68,48 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, regs->pc = (uint32_t)entry_point; } +extern void archFirstThreadRestoreLowLevel(pt_regs_t *regs); + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +void archFirstThreadRestore(ATOM_TCB *new_tcb) +{ + pt_regs_t *regs = NULL; + regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + archFirstThreadRestoreLowLevel(regs); +} + +extern int archSetJumpLowLevel(pt_regs_t *regs); +extern void archLongJumpLowLevel(pt_regs_t *regs); + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) +{ + pt_regs_t *old_regs = NULL; + pt_regs_t *new_regs = NULL; + old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + if (archSetJumpLowLevel(old_regs)) { + archLongJumpLowLevel(new_regs); + } +} + From 32fc47ef899959c8fa9944531e2993493276c474 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Tue, 5 Jul 2011 23:25:33 +0530 Subject: [PATCH 49/76] Got kern1 and kern2 test working with ARM port. Signed-off-by: Anup Patel --- ports/arm7a/Makefile | 15 +++++------ ports/arm7a/arm_main.c | 5 ---- ports/arm7a/atomport-asm.s | 53 ++++++++++++++++++++++++-------------- ports/arm7a/atomport.c | 27 ++++++++++++++----- 4 files changed, 60 insertions(+), 40 deletions(-) diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile index 816ebe8..ade2dce 100644 --- a/ports/arm7a/Makefile +++ b/ports/arm7a/Makefile @@ -75,21 +75,18 @@ TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) # Search build/output directory for dependencies -vpath %.o ./$(build_dir) -vpath %.elf ./$(build_dir) +#vpath %.o ./$(build_dir) +#vpath %.elf ./$(build_dir) # GCC flags CFLAGS= -g \ -Wall \ -Werror \ - -O \ -mcpu=$(CPU) \ - -fstrength-reduce \ - -fomit-frame-pointer \ - -finline-functions \ -nostdinc \ - -fno-builtin \ - -fno-stack-protector + -nostdlib \ + -nodefaultlibs \ + -fno-builtin # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) @@ -107,7 +104,7 @@ all: $(TEST_ELFS) Makefile $(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) $(V)mkdir -p `dirname $(build_dir)/$@` $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -nostdlib -nodefaultlibs $(build_dir)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(build_dir)/$@ -Wl -T linker.ld + $(V)$(CC) $(CFLAGS) $(build_dir)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(build_dir)/$@ -Wl -T linker.ld # Kernel objects builder $(KERNEL_OBJECTS): %.o: $(kernel_dir)/%.c diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index 4e60eba..d8ace0e 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -131,9 +131,6 @@ static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; /* Forward declarations */ static void main_thread_func (uint32_t data); -/* Global Data */ -uint32_t at_preempt_count; - /** * \b main * @@ -147,8 +144,6 @@ int main ( void ) { int8_t status; - at_preempt_count = 0; - /** * Note: to protect OS structures and data during initialisation, * interrupts must remain disabled until the first thread diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.s index ee6c1bd..fa09386 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.s @@ -29,29 +29,46 @@ #include -.section .text + .section .text + +/** + * uint32_t archGetCPSR(void) + */ + .globl archGetCPSR +archGetCPSR: + mrs r0, cpsr_all + bx lr /** * int archSetJumpLowLevel(pt_regs_t *regs) */ -.globl archSetJumpLowLevel + .globl archSetJumpLowLevel archSetJumpLowLevel: + add r0, r0, #(4 * 16) + str lr, [r0] + sub r0, r0, #(4 * 14) + stm r0, {r1-r14} + mov r0, r0 /* NOP */ + sub sp, sp, #4 + str r1, [sp] + mov r1, #0 + sub r0, r0, #4 + str r1, [r0] + mrs r1, cpsr_all + add r0, r0, #4 + str r1, [r0] + ldr r1, [sp] + sub sp, sp, #4 + mov r0, #1 bx lr /** * void archLongJumpLowLevel(pt_regs_t *regs) */ -.globl archLongJumpLowLevel + .globl archLongJumpLowLevel archLongJumpLowLevel: - bx lr - -/** - * void archFirstThreadRestoreLowLevel(pt_regs_t *regs) - */ -.globl archFirstThreadRestoreLowLevel -archFirstThreadRestoreLowLevel: add r0, r0, #(4 * 17) - mrs r1, cpsr + mrs r1, cpsr_all SET_CURRENT_MODE CPSR_MODE_UNDEFINED mov sp, r0 SET_CURRENT_MODE CPSR_MODE_ABORT @@ -60,12 +77,10 @@ archFirstThreadRestoreLowLevel: mov sp, r0 SET_CURRENT_MODE CPSR_MODE_FIQ mov sp, r0 - msr cpsr, r1 - mov sp, r0 - sub sp, sp, #(4 * 17) - ldr r0, [sp], #0x0004; /* Get CPSR from stack */ - msr spsr_all, r0; - ldmia sp, {r0-r14}; /* Restore registers */ - mov r0, r0; /* NOP for previous isnt */ - movs pc, lr + msr cpsr_all, r1 + sub r0, r0, #(4 * 17) + ldr r1, [r0], #4 /* Get CPSR from stack */ + msr cpsr_all, r1 + ldm r0, {r0-r15} + mov r0, r0 /* NOP */ diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index 67496ce..96f2cc4 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -68,7 +68,9 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, regs->pc = (uint32_t)entry_point; } -extern void archFirstThreadRestoreLowLevel(pt_regs_t *regs); +extern int archSetJumpLowLevel(pt_regs_t *regs); +extern void archLongJumpLowLevel(pt_regs_t *regs); +extern uint32_t archGetCPSR(void); /** * archFirstThreadRestore(ATOM_TCB *new_tcb) @@ -87,12 +89,9 @@ void archFirstThreadRestore(ATOM_TCB *new_tcb) pt_regs_t *regs = NULL; regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - sizeof(pt_regs_t)); - archFirstThreadRestoreLowLevel(regs); + archLongJumpLowLevel(regs); } -extern int archSetJumpLowLevel(pt_regs_t *regs); -extern void archLongJumpLowLevel(pt_regs_t *regs); - /** * Function that performs the contextSwitch. Whether its a voluntary release * of CPU by thread or a pre-emption, under both conditions this function is @@ -102,14 +101,28 @@ extern void archLongJumpLowLevel(pt_regs_t *regs); */ void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) { + uint32_t mode; + pt_regs_t tmp; pt_regs_t *old_regs = NULL; pt_regs_t *new_regs = NULL; old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr - sizeof(pt_regs_t)); new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - sizeof(pt_regs_t)); - if (archSetJumpLowLevel(old_regs)) { - archLongJumpLowLevel(new_regs); + mode = archGetCPSR() & CPSR_MODE_MASK; + if ((mode == CPSR_MODE_IRQ) || (mode == CPSR_MODE_FIQ)) { + /* Interrupt Context */ + memcpy(&tmp, old_regs, sizeof(pt_regs_t)); + if (archSetJumpLowLevel(old_regs)) { + archLongJumpLowLevel(new_regs); + } else { + memcpy(old_regs, &tmp, sizeof(pt_regs_t)); + } + } else { + /* Thread Context */ + if (archSetJumpLowLevel(old_regs)) { + archLongJumpLowLevel(new_regs); + } } } From d97eac380ee6213dc4f4b4d3b07c97b561fdb936 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 6 Jul 2011 21:23:04 +0530 Subject: [PATCH 50/76] Converted context switching functions in terms of setjump and longjump primitives. Signed-off-by: Anup Patel --- ports/arm7a/arm_main.c | 2 +- ports/arm7a/atomport-asm.s | 34 ++++++++++++++++------------------ ports/arm7a/atomport.c | 38 ++++++++++++-------------------------- 3 files changed, 29 insertions(+), 45 deletions(-) diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index d8ace0e..ec42025 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -171,7 +171,7 @@ int main ( void ) { arm_irq_setup(); - arm_timer_init(1000, 1); + arm_timer_init((1000000 / SYSTEM_TICKS_PER_SEC), 1); arm_uart_init(); diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.s index fa09386..667dea9 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.s @@ -40,34 +40,31 @@ archGetCPSR: bx lr /** - * int archSetJumpLowLevel(pt_regs_t *regs) + * int archSetJump(pt_regs_t *regs) */ - .globl archSetJumpLowLevel -archSetJumpLowLevel: + .globl archSetJump +archSetJump: add r0, r0, #(4 * 16) str lr, [r0] sub r0, r0, #(4 * 14) stm r0, {r1-r14} mov r0, r0 /* NOP */ - sub sp, sp, #4 - str r1, [sp] - mov r1, #0 + str r2, [r1] + mov r2, #0 sub r0, r0, #4 - str r1, [r0] - mrs r1, cpsr_all - add r0, r0, #4 - str r1, [r0] - ldr r1, [sp] - sub sp, sp, #4 + str r2, [r0] + mrs r2, cpsr_all + sub r0, r0, #4 + str r2, [r0] + ldr r2, [r1] mov r0, #1 bx lr /** - * void archLongJumpLowLevel(pt_regs_t *regs) + * void archLongJump(pt_regs_t *regs) */ - .globl archLongJumpLowLevel -archLongJumpLowLevel: - add r0, r0, #(4 * 17) + .globl archLongJump +archLongJump: mrs r1, cpsr_all SET_CURRENT_MODE CPSR_MODE_UNDEFINED mov sp, r0 @@ -78,9 +75,10 @@ archLongJumpLowLevel: SET_CURRENT_MODE CPSR_MODE_FIQ mov sp, r0 msr cpsr_all, r1 - sub r0, r0, #(4 * 17) ldr r1, [r0], #4 /* Get CPSR from stack */ + msr spsr_all, r1 + orr r1, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) msr cpsr_all, r1 - ldm r0, {r0-r15} + ldm r0, {r0-r15}^ mov r0, r0 /* NOP */ diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index 96f2cc4..08bb591 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -63,13 +63,13 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, for (i = 1; i < 13; i++) { regs->gpr[i] = 0x0; } - regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 2048; + regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 1024; regs->lr = (uint32_t)entry_point; regs->pc = (uint32_t)entry_point; } -extern int archSetJumpLowLevel(pt_regs_t *regs); -extern void archLongJumpLowLevel(pt_regs_t *regs); +extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); +extern void archLongJump(pt_regs_t *regs); extern uint32_t archGetCPSR(void); /** @@ -86,10 +86,9 @@ extern uint32_t archGetCPSR(void); */ void archFirstThreadRestore(ATOM_TCB *new_tcb) { - pt_regs_t *regs = NULL; - regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + pt_regs_t *regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - sizeof(pt_regs_t)); - archLongJumpLowLevel(regs); + archLongJump(regs); } /** @@ -101,28 +100,15 @@ void archFirstThreadRestore(ATOM_TCB *new_tcb) */ void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) { - uint32_t mode; - pt_regs_t tmp; - pt_regs_t *old_regs = NULL; - pt_regs_t *new_regs = NULL; - old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr + uint32_t tmp = 0x0, lr = 0x0; + pt_regs_t *old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr - sizeof(pt_regs_t)); - new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + pt_regs_t *new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - sizeof(pt_regs_t)); - mode = archGetCPSR() & CPSR_MODE_MASK; - if ((mode == CPSR_MODE_IRQ) || (mode == CPSR_MODE_FIQ)) { - /* Interrupt Context */ - memcpy(&tmp, old_regs, sizeof(pt_regs_t)); - if (archSetJumpLowLevel(old_regs)) { - archLongJumpLowLevel(new_regs); - } else { - memcpy(old_regs, &tmp, sizeof(pt_regs_t)); - } - } else { - /* Thread Context */ - if (archSetJumpLowLevel(old_regs)) { - archLongJumpLowLevel(new_regs); - } + asm volatile (" mov %0, lr\n\t" :"=r"(lr):); + if (archSetJump(old_regs, &tmp)) { + old_regs->lr = lr; + archLongJump(new_regs); } } From 3468a0d4798d6d6d1ec1cf9f54e6dc3ae5f30113 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 7 Jul 2011 12:12:57 +0530 Subject: [PATCH 51/76] Fixed kern3 and kern4 tests. (These test were creating multiple threads with same stack) Refactored code to have seperate directory for each ARM7a based board. Redesigned makefile for ARM7a port. Signed-off-by: Anup Patel --- ports/arm7a/Makefile | 168 ++++++++---------- ports/arm7a/{arm_entry.s => arm_entry.S} | 0 ports/arm7a/arm_irq.c | 17 +- ports/arm7a/arm_irq.h | 2 +- ports/arm7a/arm_main.c | 4 +- .../arm7a/{atomport-asm.s => atomport-asm.S} | 11 +- ports/arm7a/atomport.c | 1 - ports/arm7a/atomport.h | 5 +- ports/arm7a/pb-a8/Makefile | 9 + ports/arm7a/{ => pb-a8}/arm_config.h | 0 ports/arm7a/{arm_gic.c => pb-a8/arm_pic.c} | 41 ++++- ports/arm7a/{arm_gic.h => pb-a8/arm_pic.h} | 11 +- ports/arm7a/{ => pb-a8}/arm_plat.h | 0 ports/arm7a/{ => pb-a8}/arm_timer.c | 11 +- ports/arm7a/{ => pb-a8}/arm_timer.h | 2 +- ports/arm7a/{ => pb-a8}/arm_uart.c | 0 ports/arm7a/{ => pb-a8}/arm_uart.h | 0 tests/kern3.c | 38 ++-- tests/kern4.c | 76 ++++---- 19 files changed, 217 insertions(+), 179 deletions(-) rename ports/arm7a/{arm_entry.s => arm_entry.S} (100%) rename ports/arm7a/{atomport-asm.s => atomport-asm.S} (93%) create mode 100644 ports/arm7a/pb-a8/Makefile rename ports/arm7a/{ => pb-a8}/arm_config.h (100%) rename ports/arm7a/{arm_gic.c => pb-a8/arm_pic.c} (90%) rename ports/arm7a/{arm_gic.h => pb-a8/arm_pic.h} (87%) rename ports/arm7a/{ => pb-a8}/arm_plat.h (100%) rename ports/arm7a/{ => pb-a8}/arm_timer.c (92%) rename ports/arm7a/{ => pb-a8}/arm_timer.h (97%) rename ports/arm7a/{ => pb-a8}/arm_uart.c (100%) rename ports/arm7a/{ => pb-a8}/arm_uart.h (100%) diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile index ade2dce..a066851 100644 --- a/ports/arm7a/Makefile +++ b/ports/arm7a/Makefile @@ -1,24 +1,32 @@ -############ -# Settings # -############ +########################################## +# Toplevel makefile for all ARM7a boards # +########################################## -# Build all test applications: -# make -# -# Program a test application using UISP (appname => test app e.g. sems1): -# make program app=appname +# Build directory +ifdef O + build_dir=$(shell readlink -f $(O)) +else + build_dir=$(CURDIR)/build +endif -# Location of build tools and atomthreads sources -kernel_dir=../../kernel -tests_dir=../../tests - -# Directory for built objects -build_dir=build +# Source directory +src_dir=$(CURDIR) +# Configuration CPU=cortex-a8 BOARD=pb-a8 CC=$(CROSS_COMPILE)gcc OBJCOPY=$(CROSS_COMPILE)objcopy +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Location of atomthreads sources +board_dir=$(src_dir)/$(BOARD) +kernel_dir=$(src_dir)/../../kernel +tests_dir=$(src_dir)/../../tests # Check if verbosity is ON for build process VERBOSE_DEFAULT := 0 @@ -38,45 +46,36 @@ else V := $(CMD_PREFIX_DEFAULT) endif -# Enable stack-checking. WARNING: the full automated test suite currently -# requires a little over 1KB RAM with stack-checking enabled. If you are -# using a device with 1KB internal SRAM and no external SRAM then you -# must disable stack-checking to run all of the automated tests. -#STACK_CHECK=true +# object files +objs = arm_irq.o +objs += arm_main.o +objs += atomport.o +objs += arm_entry.o +objs += atomport-asm.o -# Port/application object files -APP_OBJECTS = arm_irq.o -APP_OBJECTS += arm_gic.o -APP_OBJECTS += arm_timer.o -APP_OBJECTS += arm_uart.o -APP_OBJECTS += arm_main.o -APP_OBJECTS += atomport.o -APP_OBJECTS += printk.o -APP_OBJECTS += string.o -APP_OBJECTS += vsprintf.o -APP_ASM_OBJECTS = arm_entry.o -APP_ASM_OBJECTS += atomport-asm.o +# include board makefile for board specific objects +-include $(board_dir)/Makefile + +# library object files +objs += printk.o +objs += string.o +objs += vsprintf.o # Kernel object files -KERNEL_OBJECTS = atomkernel.o -KERNEL_OBJECTS += atomsem.o -KERNEL_OBJECTS += atommutex.o -KERNEL_OBJECTS += atomtimer.o -KERNEL_OBJECTS += atomqueue.o +objs += atomkernel.o +objs += atomsem.o +objs += atommutex.o +objs += atomtimer.o +objs += atomqueue.o # Collection of built objects (excluding test applications) -ALL_OBJECTS = $(APP_ASM_OBJECTS) $(APP_OBJECTS) $(KERNEL_OBJECTS) -BUILT_OBJECTS = $(patsubst %,$(build_dir)/%,$(ALL_OBJECTS)) - -# Test object files (dealt with separately as only one per application build) -TEST_OBJECTS = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) +build_objs = $(foreach obj,$(objs),$(build_dir)/$(obj)) # Target application filenames .elf for each test object -TEST_ELFS = $(patsubst %.o,%.elf,$(TEST_OBJECTS)) - -# Search build/output directory for dependencies -#vpath %.o ./$(build_dir) -#vpath %.elf ./$(build_dir) +tobjs = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) +telfs = $(patsubst %.o,%.elf,$(tobjs)) +build_tobjs = $(foreach tobj,$(tobjs),$(build_dir)/$(tobj)) +build_telfs = $(foreach telf,$(telfs),$(build_dir)/$(telf)) # GCC flags CFLAGS= -g \ @@ -86,63 +85,54 @@ CFLAGS= -g \ -nostdinc \ -nostdlib \ -nodefaultlibs \ - -fno-builtin + -fno-builtin \ + -I$(src_dir) \ + -I$(board_dir) \ + -I$(kernel_dir) \ + -I$(tests_dir) # Enable stack-checking (disable if not required) ifeq ($(STACK_CHECK),true) CFLAGS += -DATOM_STACK_CHECKING endif -################# -# Build targets # -################# +# All +.PHONY: all +all: $(build_telfs) $(build_tobjs) $(build_objs) Makefile -# All tests -all: $(TEST_ELFS) Makefile - -# Test ELF files (one application build for each test) -$(TEST_ELFS): %.elf: %.o $(APP_ASM_OBJECTS) $(KERNEL_OBJECTS) $(APP_OBJECTS) - $(V)mkdir -p `dirname $(build_dir)/$@` - $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(build_dir)/$(notdir $<) $(BUILT_OBJECTS) -static-libgcc -lgcc --output $(build_dir)/$@ -Wl -T linker.ld - -# Kernel objects builder -$(KERNEL_OBJECTS): %.o: $(kernel_dir)/%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# Test objects builder -$(TEST_OBJECTS): %.o: $(tests_dir)/%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# Application C objects builder -$(APP_OBJECTS): %.o: ./%.c - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) $< -o $(build_dir)/$(notdir $@) - -# Application asm objects builder -$(APP_ASM_OBJECTS): %.o: ./%.s - $(V)mkdir -p `dirname $(build_dir)/$(notdir $@)` - $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") - $(V)$(CC) -c $(CFLAGS) -D__ASSEMBLY__ -x assembler-with-cpp -I. -I$(kernel_dir) $< -o $(build_dir)/$(notdir $@) - -# .lst file builder -%.lst: %.c +$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (LST) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -I. -I$(kernel_dir) -I$(tests_dir) -Wa,-al $< > $@ + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T linker.ld -o $@ + +$(build_dir)/%.o: $(src_dir)/%.S + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(src_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(kernel_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(tests_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ # Clean +.PHONY: clean clean: - $(V)rm -f *.o *.elf *.map *.bin *.lst rm -rf doxygen-kernel rm -rf doxygen-avr rm -rf $(build_dir) - +# Docs +.PHONY: doxygen doxygen: doxygen $(kernel_dir)/Doxyfile doxygen ./Doxyfile diff --git a/ports/arm7a/arm_entry.s b/ports/arm7a/arm_entry.S similarity index 100% rename from ports/arm7a/arm_entry.s rename to ports/arm7a/arm_entry.S diff --git a/ports/arm7a/arm_irq.c b/ports/arm7a/arm_irq.c index 1aec38c..cc9290d 100644 --- a/ports/arm7a/arm_irq.c +++ b/ports/arm7a/arm_irq.c @@ -29,7 +29,7 @@ #include #include -#include +#include #include arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; @@ -82,7 +82,7 @@ void do_not_used(pt_regs_t *regs) void do_irq(pt_regs_t *uregs) { int rc = 0; - int irq = arm_gic_active_irq(0); + int irq = arm_pic_active_irq(); /* Call the interrupt entry routine */ atomIntEnter(); @@ -94,7 +94,7 @@ void do_irq(pt_regs_t *uregs) while (1); } } - rc = arm_gic_ack_irq(0, irq); + rc = arm_pic_ack_irq(irq); if (rc) { while (1); } @@ -113,7 +113,7 @@ void do_fiq(pt_regs_t *uregs) atomIntExit(TRUE); } -void arm_irq_setup(void) +void arm_irq_init(void) { extern uint32_t _start_vect[]; uint32_t *vectors = (uint32_t *)NULL; @@ -150,12 +150,7 @@ void arm_irq_setup(void) /* * Initialize Generic Interrupt Controller */ - vec = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, - IRQ_PBA8_GIC_START); - if (vec) { - while(1); - } - vec = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + vec = arm_pic_init(); if (vec) { while(1); } @@ -167,7 +162,7 @@ void arm_irq_register(uint32_t irq, arm_irq_handler_t hndl) if (irq < NR_IRQS_PBA8) { irq_hndls[irq] = hndl; if (irq_hndls[irq]) { - rc = arm_gic_unmask(0, irq); + rc = arm_pic_unmask(irq); if (rc) { while (1); } diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h index 89f963f..3defb6d 100644 --- a/ports/arm7a/arm_irq.h +++ b/ports/arm7a/arm_irq.h @@ -47,7 +47,7 @@ typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); #define ARM_EXTERNAL_IRQ 6 #define ARM_EXTERNAL_FIQ 7 -void arm_irq_setup(void); +void arm_irq_init(void); void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); void arm_irq_enable(void); void arm_irq_disable(void); diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index ec42025..b0242ff 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -169,9 +169,9 @@ int main ( void ) IDLE_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { - arm_irq_setup(); + arm_irq_init(); - arm_timer_init((1000000 / SYSTEM_TICKS_PER_SEC), 1); + arm_timer_init(SYSTEM_TICKS_PER_SEC); arm_uart_init(); diff --git a/ports/arm7a/atomport-asm.s b/ports/arm7a/atomport-asm.S similarity index 93% rename from ports/arm7a/atomport-asm.s rename to ports/arm7a/atomport-asm.S index 667dea9..9208fc4 100644 --- a/ports/arm7a/atomport-asm.s +++ b/ports/arm7a/atomport-asm.S @@ -1,5 +1,6 @@ /* - * Copyright (c) 2010, Atomthreads Project. All rights reserved. + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,14 +32,6 @@ .section .text -/** - * uint32_t archGetCPSR(void) - */ - .globl archGetCPSR -archGetCPSR: - mrs r0, cpsr_all - bx lr - /** * int archSetJump(pt_regs_t *regs) */ diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c index 08bb591..de52b49 100644 --- a/ports/arm7a/atomport.c +++ b/ports/arm7a/atomport.c @@ -70,7 +70,6 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); extern void archLongJump(pt_regs_t *regs); -extern uint32_t archGetCPSR(void); /** * archFirstThreadRestore(ATOM_TCB *new_tcb) diff --git a/ports/arm7a/atomport.h b/ports/arm7a/atomport.h index debf68a..487df12 100644 --- a/ports/arm7a/atomport.h +++ b/ports/arm7a/atomport.h @@ -1,5 +1,6 @@ /* - * Copyright (c) 2011, Anup Patel. All rights reserved. + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -31,7 +32,7 @@ #define __ATOM_PORT_H /* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 100 +#define SYSTEM_TICKS_PER_SEC 1000 typedef signed int int32_t; typedef signed short int16_t; diff --git a/ports/arm7a/pb-a8/Makefile b/ports/arm7a/pb-a8/Makefile new file mode 100644 index 0000000..f44b66c --- /dev/null +++ b/ports/arm7a/pb-a8/Makefile @@ -0,0 +1,9 @@ +########################## +# Board specific objects # +########################## + +# board object files +objs += pb-a8/arm_pic.o +objs += pb-a8/arm_timer.o +objs += pb-a8/arm_uart.o + diff --git a/ports/arm7a/arm_config.h b/ports/arm7a/pb-a8/arm_config.h similarity index 100% rename from ports/arm7a/arm_config.h rename to ports/arm7a/pb-a8/arm_config.h diff --git a/ports/arm7a/arm_gic.c b/ports/arm7a/pb-a8/arm_pic.c similarity index 90% rename from ports/arm7a/arm_gic.c rename to ports/arm7a/pb-a8/arm_pic.c index 773d869..d17ef1b 100644 --- a/ports/arm7a/arm_gic.c +++ b/ports/arm7a/pb-a8/arm_pic.c @@ -29,7 +29,7 @@ #include #include -#include +#include #define max(a,b) ((a) < (b) ? (b) : (a)) @@ -206,3 +206,42 @@ int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base) return 0; } + +int arm_pic_active_irq(void) +{ + return arm_gic_active_irq(0); +} + +int arm_pic_ack_irq(uint32_t irq) +{ + return arm_gic_ack_irq(0, irq); +} + +int arm_pic_mask(uint32_t irq) +{ + return arm_gic_mask(0, irq); +} + +int arm_pic_unmask(uint32_t irq) +{ + return arm_gic_unmask(0, irq); +} + +int arm_pic_init(void) +{ + int rc = 0; + + rc = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, + IRQ_PBA8_GIC_START); + if (rc) { + return rc; + } + rc = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + if (rc) { + while(1); + } + + return rc; +} + + diff --git a/ports/arm7a/arm_gic.h b/ports/arm7a/pb-a8/arm_pic.h similarity index 87% rename from ports/arm7a/arm_gic.h rename to ports/arm7a/pb-a8/arm_pic.h index cca8c77..d3485f0 100644 --- a/ports/arm7a/arm_gic.h +++ b/ports/arm7a/pb-a8/arm_pic.h @@ -52,11 +52,10 @@ #define GIC_DIST_CONFIG 0xc00 #define GIC_DIST_SOFTINT 0xf00 -int arm_gic_active_irq(uint32_t gic_nr); -int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq); -int arm_gic_mask(uint32_t gic_nr, uint32_t irq); -int arm_gic_unmask(uint32_t gic_nr, uint32_t irq); -int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start); -int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base); +int arm_pic_active_irq(void); +int arm_pic_ack_irq(uint32_t irq); +int arm_pic_mask(uint32_t irq); +int arm_pic_unmask(uint32_t irq); +int arm_pic_init(void); #endif diff --git a/ports/arm7a/arm_plat.h b/ports/arm7a/pb-a8/arm_plat.h similarity index 100% rename from ports/arm7a/arm_plat.h rename to ports/arm7a/pb-a8/arm_plat.h diff --git a/ports/arm7a/arm_timer.c b/ports/arm7a/pb-a8/arm_timer.c similarity index 92% rename from ports/arm7a/arm_timer.c rename to ports/arm7a/pb-a8/arm_timer.c index ed5b359..e3f753f 100644 --- a/ports/arm7a/arm_timer.c +++ b/ports/arm7a/pb-a8/arm_timer.c @@ -70,16 +70,15 @@ int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) return 0; } -int arm_timer_init(uint32_t usecs, uint32_t ensel) +int arm_timer_init(uint32_t ticks_per_sec) { uint32_t val; /* * set clock frequency: - * REALVIEW_REFCLK is 32KHz * REALVIEW_TIMCLK is 1MHz */ - val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << ensel); + val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << 0x1); arm_writel(val, (void *)REALVIEW_SCTL_BASE); /* Register interrupt handler */ @@ -89,8 +88,10 @@ int arm_timer_init(uint32_t usecs, uint32_t ensel) val &= ~TIMER_CTRL_ENABLE; val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); arm_writel(val, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); - arm_writel(usecs, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); return 0; } diff --git a/ports/arm7a/arm_timer.h b/ports/arm7a/pb-a8/arm_timer.h similarity index 97% rename from ports/arm7a/arm_timer.h rename to ports/arm7a/pb-a8/arm_timer.h index 45bf35c..23c921c 100644 --- a/ports/arm7a/arm_timer.h +++ b/ports/arm7a/pb-a8/arm_timer.h @@ -51,6 +51,6 @@ void arm_timer_enable(void); void arm_timer_disable(void); void arm_timer_clearirq(void); -int arm_timer_init(uint32_t usecs, uint32_t ensel); +int arm_timer_init(uint32_t ticks_per_sec); #endif /* __ARM_TIMER_H */ diff --git a/ports/arm7a/arm_uart.c b/ports/arm7a/pb-a8/arm_uart.c similarity index 100% rename from ports/arm7a/arm_uart.c rename to ports/arm7a/pb-a8/arm_uart.c diff --git a/ports/arm7a/arm_uart.h b/ports/arm7a/pb-a8/arm_uart.h similarity index 100% rename from ports/arm7a/arm_uart.h rename to ports/arm7a/pb-a8/arm_uart.h diff --git a/tests/kern3.c b/tests/kern3.c index a149d72..d54312f 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -45,9 +45,9 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE]; static volatile int running_flag[2]; static volatile int sleep_request[2]; - /* Forward declarations */ static void test_thread_func (uint32_t param); +static int test_iter = 0; /** @@ -93,23 +93,29 @@ uint32_t test_start (void) running_flag[0] = running_flag[1] = FALSE; sleep_request[0] = sleep_request[1] = FALSE; - /* Create low priority thread */ - if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; + /* Create threads in first iteration only */ + if (test_iter == 0) { + /* Create low priority thread */ + if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + + /* Create high priority thread */ + else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } } - /* Create high priority thread */ - else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } + /* Increment test iteration count */ + test_iter++; /* Repeat test a few times */ for (i = 0; i < 8; i++) diff --git a/tests/kern4.c b/tests/kern4.c index 23ed33b..253b05a 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -51,7 +51,7 @@ static int volatile test_started; /* Forward declarations */ static void test_thread_func (uint32_t param); - +static int test_iter = 0; /** * \b test_start @@ -89,42 +89,48 @@ uint32_t test_start (void) /* Set test as not started until all threads are ready to go */ test_started = FALSE; - /* - * Create all four threads at the same priority as each other. - * They are given a lower priority than this thread, however, - * to ensure that once this thread wakes up to stop the test it - * can do so without confusing the scheduling tests by having - * a spell in which this thread was run. - */ - if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, - &test_thread_stack[2][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, - &test_thread_stack[3][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; + /* Create threads in first iteration only */ + if (test_iter == 0) { + /* + * Create all four threads at the same priority as each other. + * They are given a lower priority than this thread, however, + * to ensure that once this thread wakes up to stop the test it + * can do so without confusing the scheduling tests by having + * a spell in which this thread was run. + */ + if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } } + /* Increment test iteration count */ + test_iter++; + /* Start the test */ test_started = TRUE; From a88b9b542e0e3c5d22dbeaa225ebcdf80c67b404 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 7 Jul 2011 14:42:37 +0530 Subject: [PATCH 52/76] Reverted kern3 and kern4 test. Fixed main_thread_func() to call test_start() only once. Signed-off-by: Anup Patel --- ports/arm7a/arm_main.c | 17 +++++----- tests/kern3.c | 38 +++++++++------------ tests/kern4.c | 76 +++++++++++++++++++----------------------- 3 files changed, 60 insertions(+), 71 deletions(-) diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c index b0242ff..5546e7d 100644 --- a/ports/arm7a/arm_main.c +++ b/ports/arm7a/arm_main.c @@ -218,13 +218,14 @@ int main ( void ) */ static void main_thread_func (uint32_t data) { - while (1) { - /* Put a message out on the UART */ - printk("Running Tests... "); - if (test_start() != 0) { - printk("FAILED!\n"); - } else { - printk("SUCCESS!\n"); - } + /* Put a message out on the UART */ + printk("Test Started ... "); + if (test_start() != 0) { + printk("FAILED!\n"); + } else { + printk("SUCCESS!\n"); } + printk("Reset your board !!!!!"); + /* Test finished so just hang !!! */ + while (1); } diff --git a/tests/kern3.c b/tests/kern3.c index d54312f..a149d72 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -45,9 +45,9 @@ static uint8_t test_thread_stack[NUM_TEST_THREADS][TEST_THREAD_STACK_SIZE]; static volatile int running_flag[2]; static volatile int sleep_request[2]; + /* Forward declarations */ static void test_thread_func (uint32_t param); -static int test_iter = 0; /** @@ -93,29 +93,23 @@ uint32_t test_start (void) running_flag[0] = running_flag[1] = FALSE; sleep_request[0] = sleep_request[1] = FALSE; - /* Create threads in first iteration only */ - if (test_iter == 0) { - /* Create low priority thread */ - if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - - /* Create high priority thread */ - else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } + /* Create low priority thread */ + if (atomThreadCreate (&tcb[0], 253, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; } - /* Increment test iteration count */ - test_iter++; + /* Create high priority thread */ + else if (atomThreadCreate (&tcb[1], 252, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } /* Repeat test a few times */ for (i = 0; i < 8; i++) diff --git a/tests/kern4.c b/tests/kern4.c index 253b05a..23ed33b 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -51,7 +51,7 @@ static int volatile test_started; /* Forward declarations */ static void test_thread_func (uint32_t param); -static int test_iter = 0; + /** * \b test_start @@ -89,47 +89,41 @@ uint32_t test_start (void) /* Set test as not started until all threads are ready to go */ test_started = FALSE; - /* Create threads in first iteration only */ - if (test_iter == 0) { - /* - * Create all four threads at the same priority as each other. - * They are given a lower priority than this thread, however, - * to ensure that once this thread wakes up to stop the test it - * can do so without confusing the scheduling tests by having - * a spell in which this thread was run. - */ - if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, - &test_thread_stack[0][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, - &test_thread_stack[1][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, - &test_thread_stack[2][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } - else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, - &test_thread_stack[3][0], - TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) - { - ATOMLOG (_STR("Bad thread create\n")); - failures++; - } + /* + * Create all four threads at the same priority as each other. + * They are given a lower priority than this thread, however, + * to ensure that once this thread wakes up to stop the test it + * can do so without confusing the scheduling tests by having + * a spell in which this thread was run. + */ + if (atomThreadCreate (&tcb[0], TEST_THREAD_PRIO + 1, test_thread_func, 0, + &test_thread_stack[0][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[1], TEST_THREAD_PRIO + 1, test_thread_func, 1, + &test_thread_stack[1][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[2], TEST_THREAD_PRIO + 1, test_thread_func, 2, + &test_thread_stack[2][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; + } + else if (atomThreadCreate (&tcb[3], TEST_THREAD_PRIO + 1, test_thread_func, 3, + &test_thread_stack[3][0], + TEST_THREAD_STACK_SIZE, TRUE) != ATOM_OK) + { + ATOMLOG (_STR("Bad thread create\n")); + failures++; } - - /* Increment test iteration count */ - test_iter++; /* Start the test */ test_started = TRUE; From 1239eb1827544c52cd28689ec59c457187dae774 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 7 Jul 2011 17:35:38 +0530 Subject: [PATCH 53/76] Renamed directory from arm7a to armv7a to mean "ARM v7 Application" Architecture. Signed-off-by: Anup Patel --- ports/arm7a/Doxyfile | 1161 -------------------------------- ports/arm7a/Makefile | 138 ---- ports/arm7a/arm_asm_macro.h | 123 ---- ports/arm7a/arm_defines.h | 68 -- ports/arm7a/arm_entry.S | 151 ----- ports/arm7a/arm_io.h | 45 -- ports/arm7a/arm_irq.c | 201 ------ ports/arm7a/arm_irq.h | 57 -- ports/arm7a/arm_main.c | 231 ------- ports/arm7a/atomport-asm.S | 77 --- ports/arm7a/atomport-tests.h | 48 -- ports/arm7a/atomport.c | 113 ---- ports/arm7a/atomport.h | 85 --- ports/arm7a/linker.ld | 74 -- ports/arm7a/pb-a8/Makefile | 9 - ports/arm7a/pb-a8/arm_config.h | 147 ---- ports/arm7a/pb-a8/arm_pic.c | 247 ------- ports/arm7a/pb-a8/arm_pic.h | 61 -- ports/arm7a/pb-a8/arm_plat.h | 287 -------- ports/arm7a/pb-a8/arm_timer.c | 97 --- ports/arm7a/pb-a8/arm_timer.h | 56 -- ports/arm7a/pb-a8/arm_uart.c | 112 --- ports/arm7a/pb-a8/arm_uart.h | 110 --- ports/arm7a/printk.c | 59 -- ports/arm7a/printk.h | 42 -- ports/arm7a/stdarg.h | 28 - ports/arm7a/string.c | 61 -- ports/arm7a/string.h | 42 -- ports/arm7a/system.h | 52 -- ports/arm7a/vsprintf.c | 244 ------- 30 files changed, 4226 deletions(-) delete mode 100644 ports/arm7a/Doxyfile delete mode 100644 ports/arm7a/Makefile delete mode 100644 ports/arm7a/arm_asm_macro.h delete mode 100644 ports/arm7a/arm_defines.h delete mode 100644 ports/arm7a/arm_entry.S delete mode 100644 ports/arm7a/arm_io.h delete mode 100644 ports/arm7a/arm_irq.c delete mode 100644 ports/arm7a/arm_irq.h delete mode 100644 ports/arm7a/arm_main.c delete mode 100644 ports/arm7a/atomport-asm.S delete mode 100644 ports/arm7a/atomport-tests.h delete mode 100644 ports/arm7a/atomport.c delete mode 100644 ports/arm7a/atomport.h delete mode 100755 ports/arm7a/linker.ld delete mode 100644 ports/arm7a/pb-a8/Makefile delete mode 100644 ports/arm7a/pb-a8/arm_config.h delete mode 100644 ports/arm7a/pb-a8/arm_pic.c delete mode 100644 ports/arm7a/pb-a8/arm_pic.h delete mode 100644 ports/arm7a/pb-a8/arm_plat.h delete mode 100644 ports/arm7a/pb-a8/arm_timer.c delete mode 100644 ports/arm7a/pb-a8/arm_timer.h delete mode 100644 ports/arm7a/pb-a8/arm_uart.c delete mode 100644 ports/arm7a/pb-a8/arm_uart.h delete mode 100644 ports/arm7a/printk.c delete mode 100644 ports/arm7a/printk.h delete mode 100755 ports/arm7a/stdarg.h delete mode 100644 ports/arm7a/string.c delete mode 100644 ports/arm7a/string.h delete mode 100644 ports/arm7a/system.h delete mode 100644 ports/arm7a/vsprintf.c diff --git a/ports/arm7a/Doxyfile b/ports/arm7a/Doxyfile deleted file mode 100644 index e6f6571..0000000 --- a/ports/arm7a/Doxyfile +++ /dev/null @@ -1,1161 +0,0 @@ -# Doxyfile 1.3.9.1 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = atomthreads - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = doxygen-avr - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of source -# files, where putting all generated files in the same directory would otherwise -# cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, -# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, -# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, -# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, -# Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is used -# as the annotated text. Otherwise, the brief description is used as-is. If left -# blank, the following values are used ("$name" is automatically replaced with the -# name of the entity): "The $name class" "The $name widget" "The $name file" -# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited -# members of a class in the documentation of that class as if those members were -# ordinary class members. Constructors, destructors and assignment operators of -# the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = YES - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 4 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources -# only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources -# only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = YES - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = YES - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. - -SHOW_DIRECTORIES = YES - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = NO - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -WARN_IF_UNDOCUMENTED = YES - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp -# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories -# that are symbolic links (a Unix filesystem feature) are excluded from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = html - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_PREDEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse the -# parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or -# super classes. Setting the tag to NO turns the diagrams off. Note that this -# option is superseded by the HAVE_DOT option below. This is only a fallback. It is -# recommended to install and use dot, since it yields more powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = NO - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found on the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes that -# lay further from the root node will be omitted. Note that setting this option to -# 1 or 2 may greatly reduce the computation time needed for large code bases. Also -# note that a graph may be further truncated if the graph's image dimensions are -# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). -# If 0 is used for the depth value (the default), the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO diff --git a/ports/arm7a/Makefile b/ports/arm7a/Makefile deleted file mode 100644 index a066851..0000000 --- a/ports/arm7a/Makefile +++ /dev/null @@ -1,138 +0,0 @@ -########################################## -# Toplevel makefile for all ARM7a boards # -########################################## - -# Build directory -ifdef O - build_dir=$(shell readlink -f $(O)) -else - build_dir=$(CURDIR)/build -endif - -# Source directory -src_dir=$(CURDIR) - -# Configuration -CPU=cortex-a8 -BOARD=pb-a8 -CC=$(CROSS_COMPILE)gcc -OBJCOPY=$(CROSS_COMPILE)objcopy -# Enable stack-checking. WARNING: the full automated test suite currently -# requires a little over 1KB RAM with stack-checking enabled. If you are -# using a device with 1KB internal SRAM and no external SRAM then you -# must disable stack-checking to run all of the automated tests. -#STACK_CHECK=true - -# Location of atomthreads sources -board_dir=$(src_dir)/$(BOARD) -kernel_dir=$(src_dir)/../../kernel -tests_dir=$(src_dir)/../../tests - -# Check if verbosity is ON for build process -VERBOSE_DEFAULT := 0 -CMD_PREFIX_DEFAULT := @ -ifdef VERBOSE - ifeq ("$(origin VERBOSE)", "command line") - VB := $(VERBOSE) - else - VB := $(VERBOSE_DEFAULT) - endif -else - VB := $(VERBOSE_DEFAULT) -endif -ifeq ($(VB), 1) - V := -else - V := $(CMD_PREFIX_DEFAULT) -endif - -# object files -objs = arm_irq.o -objs += arm_main.o -objs += atomport.o -objs += arm_entry.o -objs += atomport-asm.o - -# include board makefile for board specific objects --include $(board_dir)/Makefile - -# library object files -objs += printk.o -objs += string.o -objs += vsprintf.o - -# Kernel object files -objs += atomkernel.o -objs += atomsem.o -objs += atommutex.o -objs += atomtimer.o -objs += atomqueue.o - -# Collection of built objects (excluding test applications) -build_objs = $(foreach obj,$(objs),$(build_dir)/$(obj)) - -# Target application filenames .elf for each test object -tobjs = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) -telfs = $(patsubst %.o,%.elf,$(tobjs)) -build_tobjs = $(foreach tobj,$(tobjs),$(build_dir)/$(tobj)) -build_telfs = $(foreach telf,$(telfs),$(build_dir)/$(telf)) - -# GCC flags -CFLAGS= -g \ - -Wall \ - -Werror \ - -mcpu=$(CPU) \ - -nostdinc \ - -nostdlib \ - -nodefaultlibs \ - -fno-builtin \ - -I$(src_dir) \ - -I$(board_dir) \ - -I$(kernel_dir) \ - -I$(tests_dir) - -# Enable stack-checking (disable if not required) -ifeq ($(STACK_CHECK),true) -CFLAGS += -DATOM_STACK_CHECKING -endif - -# All -.PHONY: all -all: $(build_telfs) $(build_tobjs) $(build_objs) Makefile - -$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) - $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T linker.ld -o $@ - -$(build_dir)/%.o: $(src_dir)/%.S - $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@ - -$(build_dir)/%.o: $(src_dir)/%.c - $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ - -$(build_dir)/%.o: $(kernel_dir)/%.c - $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ - -$(build_dir)/%.o: $(tests_dir)/%.c - $(V)mkdir -p `dirname $@` - $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ - -# Clean -.PHONY: clean -clean: - rm -rf doxygen-kernel - rm -rf doxygen-avr - rm -rf $(build_dir) -# Docs -.PHONY: doxygen -doxygen: - doxygen $(kernel_dir)/Doxyfile - doxygen ./Doxyfile diff --git a/ports/arm7a/arm_asm_macro.h b/ports/arm7a/arm_asm_macro.h deleted file mode 100644 index 4d833b3..0000000 --- a/ports/arm7a/arm_asm_macro.h +++ /dev/null @@ -1,123 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_ASM_MACRO_H__ -#define __ARM_ASM_MACRO_H__ - -#include - -#ifdef __ASSEMBLY__ - -.macro SET_CURRENT_FLAGS flags, treg - mrs \treg, cpsr - orr \treg, \treg, #(\flags) - msr cpsr, \treg -.endm - -.macro SET_CURRENT_MODE mode - cps #(\mode) -.endm - -.macro SET_CURRENT_STACK new_stack - ldr sp, \new_stack -.endm - -.macro START_EXCEPTION_HANDLER irqname, lroffset - .align 5 -\irqname: - sub lr, lr, #\lroffset -.endm - -/* Save User Registers */ -.macro PUSH_USER_REGS - str lr, [sp, #-4]!; /* Push the return address */ - sub sp, sp, #(4*15); /* Adjust the stack pointer */ - stmia sp, {r0-r12}; /* Push user mode registers */ - add r0, sp, #(4*13); /* Adjust the stack pointer */ - stmia r0, {r13-r14}^; /* Push user mode registers */ - mov r0, r0; /* NOP for previous inst */ - mrs r0, spsr_all; /* Put the SPSR on the stack */ - str r0, [sp, #-4]! -.endm - -/* If came from priviledged mode then push banked registers */ -.macro PUSH_BANKED_REGS skip_lable - mov r4, r0 - and r0, r0, #CPSR_MODE_MASK - cmp r0, #CPSR_MODE_USER - beq \skip_lable - add r1, sp, #(4*14) - mrs r5, cpsr - orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) - msr cpsr, r4 - str sp, [r1, #0] - str lr, [r1, #4] - msr cpsr, r5 - \skip_lable: -.endm - -/* Call C function to handle exception */ -.macro CALL_EXCEPTION_CFUNC cfunc - mov r0, sp - bl \cfunc -.endm - -/* If going back to priviledged mode then pull banked registers */ -.macro PULL_BANKED_REGS skip_lable - ldr r0, [sp, #0] - mov r4, r0 - and r0, r0, #CPSR_MODE_MASK - cmp r0, #CPSR_MODE_USER - beq \skip_lable - add r1, sp, #(4*14) - mrs r5, cpsr - orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) - msr cpsr, r4 - ldr sp, [r1, #0] - ldr lr, [r1, #4] - msr cpsr, r5 - \skip_lable: -.endm - -/* Restore User Registers */ -.macro PULL_USER_REGS - ldr r0, [sp], #0x0004; /* Get SPSR from stack */ - msr spsr_all, r0; - ldmia sp, {r0-r14}^; /* Restore registers (user) */ - mov r0, r0; /* NOP for previous isnt */ - add sp, sp, #(4*15); /* Adjust the stack pointer */ - ldr lr, [sp], #0x0004 /* Pull return address */ -.endm - -.macro END_EXCEPTION_HANDLER - movs pc, lr -.endm - -#endif - -#endif diff --git a/ports/arm7a/arm_defines.h b/ports/arm7a/arm_defines.h deleted file mode 100644 index 8de737c..0000000 --- a/ports/arm7a/arm_defines.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_DEFINES_H_ -#define __ARM_DEFINES_H_ - -#define CPSR_VALIDBITS_MASK 0xFF0FFFFF -#define CPSR_USERBITS_MASK 0xFFFFFC00 -#define CPSR_USERBITS_SHIFT 10 -#define CPSR_PRIVBITS_MASK 0x000003FF -#define CPSR_PRIVBITS_SHIFT 0 -#define CPSR_MODE_MASK 0x0000001f -#define CPSR_MODE_USER 0x00000010 -#define CPSR_MODE_FIQ 0x00000011 -#define CPSR_MODE_IRQ 0x00000012 -#define CPSR_MODE_SUPERVISOR 0x00000013 -#define CPSR_MODE_MONITOR 0x00000016 -#define CPSR_MODE_ABORT 0x00000017 -#define CPSR_MODE_UNDEFINED 0x0000001b -#define CPSR_MODE_SYSTEM 0x0000001f -#define CPSR_THUMB_ENABLED (1 << 5) -#define CPSR_FIQ_DISABLED (1 << 6) -#define CPSR_IRQ_DISABLED (1 << 7) -#define CPSR_ASYNC_ABORT_DISABLED (1 << 8) -#define CPSR_BE_ENABLED (1 << 9) -#define CPSR_IT2_MASK 0x0000FC00 -#define CPSR_IT2_SHIFT 10 -#define CPSR_GE_MASK 0x000F0000 -#define CPSR_GE_SHIFT 16 -#define CPSR_JAZZLE_ENABLED (1 << 24) -#define CPSR_IT1_MASK 0x06000000 -#define CPSR_IT1_SHIFT 25 -#define CPSR_COND_OVERFLOW_MASK (1 << 28) -#define CPSR_COND_OVERFLOW_SHIFT 28 -#define CPSR_COND_CARRY_MASK (1 << 29) -#define CPSR_COND_CARRY_SHIFT 29 -#define CPSR_COND_ZERO_MASK (1 << 30) -#define CPSR_COND_ZERO_SHIFT 30 -#define CPSR_COND_NEGATIVE_MASK (1 << 31) -#define CPSR_COND_NEGATIVE_SHIFT 31 - -#endif /* __ARM_DEFINES_H_ */ diff --git a/ports/arm7a/arm_entry.S b/ports/arm7a/arm_entry.S deleted file mode 100644 index 9f21d94..0000000 --- a/ports/arm7a/arm_entry.S +++ /dev/null @@ -1,151 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 - - .section .expvect, "ax", %progbits - .globl _start_vect -_start_vect: - ldr pc, __reset - ldr pc, __undefined_instruction - ldr pc, __software_interrupt - ldr pc, __prefetch_abort - ldr pc, __data_abort - ldr pc, __not_used - ldr pc, __irq - ldr pc, __fiq -__reset: - .word _reset -__undefined_instruction: - .word _undefined_instruction -__software_interrupt: - .word _software_interrupt -__prefetch_abort: - .word _prefetch_abort -__data_abort: - .word _data_abort -__not_used: - .word _not_used -__irq: - .word _irq -__fiq: - .word _fiq - .global _end_vect -_end_vect: - -__initial_stack_end: - .word _initial_stack_end - - .globl _reset -_reset: - /* Clear a register for temporary usage */ - mov r8, #0 - /* Disable IRQ & FIQ */ - cpsid if - /* Set Supervisor Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_SUPERVISOR - SET_CURRENT_STACK __initial_stack_end - /* Set Undefined Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_UNDEFINED - SET_CURRENT_STACK __initial_stack_end - /* Set Abort Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_ABORT - SET_CURRENT_STACK __initial_stack_end - /* Set IRQ Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_IRQ - SET_CURRENT_STACK __initial_stack_end - /* Set FIQ Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_FIQ - SET_CURRENT_STACK __initial_stack_end - /* Set System Mode Stack */ - SET_CURRENT_MODE CPSR_MODE_SYSTEM - SET_CURRENT_STACK __initial_stack_end - /* Set to Supervisor Mode */ - SET_CURRENT_MODE CPSR_MODE_SUPERVISOR - /* Call main function */ - bl main - /* We should never reach here */ - b . - -START_EXCEPTION_HANDLER _undefined_instruction, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _undefined_instruction_bankpush_skip - CALL_EXCEPTION_CFUNC do_undefined_instruction - PULL_BANKED_REGS _undefined_instruction_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _software_interrupt, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _software_interrupt_bankpush_skip - CALL_EXCEPTION_CFUNC do_software_interrupt - PULL_BANKED_REGS _software_interrupt_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _prefetch_abort, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _prefetch_abort_bankpush_skip - CALL_EXCEPTION_CFUNC do_prefetch_abort - PULL_BANKED_REGS _prefetch_abort_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _data_abort, 8 - PUSH_USER_REGS - PUSH_BANKED_REGS _data_abort_bankpush_skip - CALL_EXCEPTION_CFUNC do_data_abort - PULL_BANKED_REGS _data_abort_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _not_used, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _not_used_bankpush_skip - CALL_EXCEPTION_CFUNC do_not_used - PULL_BANKED_REGS _not_used_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _irq, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _irq_bankpush_skip - CALL_EXCEPTION_CFUNC do_irq - PULL_BANKED_REGS _irq_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - -START_EXCEPTION_HANDLER _fiq, 4 - PUSH_USER_REGS - PUSH_BANKED_REGS _fiq_bankpush_skip - CALL_EXCEPTION_CFUNC do_fiq - PULL_BANKED_REGS _fiq_bankpull_skip - PULL_USER_REGS -END_EXCEPTION_HANDLER - diff --git a/ports/arm7a/arm_io.h b/ports/arm7a/arm_io.h deleted file mode 100644 index 950a938..0000000 --- a/ports/arm7a/arm_io.h +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IO_H_ -#define __ARM_IO_H_ - -#include - -static inline uint32_t arm_readl(void * addr) -{ - return *((uint32_t *)addr); -} - -static inline void arm_writel(uint32_t data, void * addr) -{ - *((uint32_t *)addr) = data; -} - -#endif /* __ARM_IO_H_ */ diff --git a/ports/arm7a/arm_irq.c b/ports/arm7a/arm_irq.c deleted file mode 100644 index cc9290d..0000000 --- a/ports/arm7a/arm_irq.c +++ /dev/null @@ -1,201 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include -#include -#include - -arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; - -void do_undefined_instruction(pt_regs_t *regs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_software_interrupt(pt_regs_t *regs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_prefetch_abort(pt_regs_t *regs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_data_abort(pt_regs_t *regs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_not_used(pt_regs_t *regs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_irq(pt_regs_t *uregs) -{ - int rc = 0; - int irq = arm_pic_active_irq(); - - /* Call the interrupt entry routine */ - atomIntEnter(); - - if (-1 < irq) { - if (irq_hndls[irq]) { - rc = irq_hndls[irq](irq, uregs); - if (rc) { - while (1); - } - } - rc = arm_pic_ack_irq(irq); - if (rc) { - while (1); - } - } - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void do_fiq(pt_regs_t *uregs) -{ - /* Call the interrupt entry routine */ - atomIntEnter(); - - /* Call the interrupt exit routine */ - atomIntExit(TRUE); -} - -void arm_irq_init(void) -{ - extern uint32_t _start_vect[]; - uint32_t *vectors = (uint32_t *)NULL; - uint32_t *vectors_data = vectors + CPU_IRQ_NR; - int vec; - - /* - * Loop through the vectors we're taking over, and copy the - * vector's insn and data word. - */ - for (vec = 0; vec < CPU_IRQ_NR; vec++) { - vectors[vec] = _start_vect[vec]; - vectors_data[vec] = _start_vect[vec+CPU_IRQ_NR]; - } - - /* - * Check if verctors are set properly - */ - for (vec = 0; vec < CPU_IRQ_NR; vec++) { - if ((vectors[vec] != _start_vect[vec]) || - (vectors_data[vec] != _start_vect[vec+CPU_IRQ_NR])) { - /* Hang */ - while(1); - } - } - - /* - * Reset irq handlers - */ - for (vec = 0; vec < NR_IRQS_PBA8; vec++) { - irq_hndls[vec] = NULL; - } - - /* - * Initialize Generic Interrupt Controller - */ - vec = arm_pic_init(); - if (vec) { - while(1); - } -} - -void arm_irq_register(uint32_t irq, arm_irq_handler_t hndl) -{ - int rc = 0; - if (irq < NR_IRQS_PBA8) { - irq_hndls[irq] = hndl; - if (irq_hndls[irq]) { - rc = arm_pic_unmask(irq); - if (rc) { - while (1); - } - } - } -} - -void arm_irq_enable(void) -{ - __asm( "cpsie if" ); -} - -void arm_irq_disable(void) -{ - __asm( "cpsid if" ); -} - -irq_flags_t arm_irq_save(void) -{ - unsigned long retval; - - asm volatile (" mrs %0, cpsr\n\t" " cpsid i" /* Syntax CPSID {, #} - * Note: This instruction is supported - * from ARM6 and above - */ - :"=r" (retval)::"memory", "cc"); - - return retval; -} - -void arm_irq_restore(irq_flags_t flags) -{ - asm volatile (" msr cpsr_c, %0"::"r" (flags) - :"memory", "cc"); -} - diff --git a/ports/arm7a/arm_irq.h b/ports/arm7a/arm_irq.h deleted file mode 100644 index 3defb6d..0000000 --- a/ports/arm7a/arm_irq.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IRQ_H -#define __ARM_IRQ_H - -#include -#include - -typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); - -#define CPU_IRQ_NR 8 - -/** IRQ Numbers */ -#define ARM_RESET_IRQ 0 -#define ARM_UNDEF_INST_IRQ 1 -#define ARM_SOFT_IRQ 2 -#define ARM_PREFETCH_ABORT_IRQ 3 -#define ARM_DATA_ABORT_IRQ 4 -#define ARM_NOT_USED_IRQ 5 -#define ARM_EXTERNAL_IRQ 6 -#define ARM_EXTERNAL_FIQ 7 - -void arm_irq_init(void); -void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); -void arm_irq_enable(void); -void arm_irq_disable(void); -irq_flags_t arm_irq_save(void); -void arm_irq_restore(irq_flags_t flags); - -#endif /* __ARM_IRQ_H */ diff --git a/ports/arm7a/arm_main.c b/ports/arm7a/arm_main.c deleted file mode 100644 index 5546e7d..0000000 --- a/ports/arm7a/arm_main.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include -#include -#include -#include "system.h" -#include -#include -#include - -/* Constants */ - -/* - * Idle thread stack size - * - * This needs to be large enough to handle any interrupt handlers - * and callbacks called by interrupt handlers (e.g. user-created - * timer callbacks) as well as the saving of all context when - * switching away from this thread. - * - * In this case, the idle stack is allocated on the BSS via the - * idle_thread_stack[] byte array. - */ -#define IDLE_STACK_SIZE_BYTES 8192 - - -/* - * Main thread stack size - * - * Note that this is not a required OS kernel thread - you will replace - * this with your own application thread. - * - * In this case the Main thread is responsible for calling out to the - * test routines. Once a test routine has finished, the test status is - * printed out on the UART and the thread remains running in a loop - * flashing a LED. - * - * The Main thread stack generally needs to be larger than the idle - * thread stack, as not only does it need to store interrupt handler - * stack saves and context switch saves, but the application main thread - * will generally be carrying out more nested function calls and require - * stack for application code local variables etc. - * - * With all OS tests implemented to date on the AVR, the Main thread - * stack has not exceeded 198 bytes. To allow all tests to run we set - * a minimum main thread stack size of 204 bytes. This may increase in - * future as the codebase changes but for the time being is enough to - * cope with all of the automated tests. - */ -#define MAIN_STACK_SIZE_BYTES 8192 - - -/* - * Startup code stack - * - * Some stack space is required at initial startup for running the main() - * routine. This stack space is only temporarily required at first bootup - * and is no longer required as soon as the OS is started. By default - * GCC sets this to the top of RAM (RAMEND) and it grows down from there. - * Because we only need this temporarily, though, it would be wasteful to - * set aside a region at the top of RAM which is not used during runtime. - * - * What we do here is to reuse part of the idle thread's stack during - * initial startup. As soon as we enter the main() routine we move the - * stack pointer to half-way down the idle thread's stack. This is used - * temporarily while calls are made to atomOSInit(), atomThreadCreate() - * and atomOSStart(). Once the OS is started this stack area is no - * longer required, and can be used for its original purpose (for the - * idle thread's stack). - * - * This does mean, however, that we cannot monitor the stack usage of the - * idle thread. Stack usage is monitored by prefilling the stack with a - * known value, and we are obliterating some of that prefilled area by - * using it as our startup stack, so we cannot use the stack-checking API - * to get a true picture of idle thread stack usage. If you wish to - * monitor idle thread stack usage for your applications then you are - * free to use a different region for the startup stack (e.g. set aside - * an area permanently, or place it somewhere you know you can reuse - * later in the application). For the time being, this method gives us a - * simple way of reducing the memory consumption without having to add - * any special AVR-specific considerations to the automated test - * applications. - * - * This optimisation was required to allow some of the larger automated - * test modules to run on devices with 1KB of RAM. You should avoid doing - * this if you can afford to set aside 64 bytes or so, or if you are - * writing your own applications in which you have further control over - * where data is located. - */ - - -/* Local data */ - -/* Application threads' TCBs */ -static ATOM_TCB main_tcb; - -/* Main thread's stack area */ -static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; - -/* Idle thread's stack area */ -static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; - -/* Forward declarations */ -static void main_thread_func (uint32_t data); - -/** - * \b main - * - * Program entry point. - * - * Sets up the AVR hardware resources (system tick timer interrupt) necessary - * for the OS to be started. Creates an application thread and starts the OS. - */ - -int main ( void ) -{ - int8_t status; - - /** - * Note: to protect OS structures and data during initialisation, - * interrupts must remain disabled until the first thread - * has been restored. They are reenabled at the very end of - * the first thread restore, at which point it is safe for a - * reschedule to take place. - */ - - /** - * Initialise the OS before creating our threads. - * - * Note that we tell the OS that the idle stack is half its actual - * size. This prevents it prefilling the bottom half with known - * values for stack-checkig purposes, which we cannot allow because - * we are temporarily using it for our own stack. The remainder will - * still be available once the OS is started, this only prevents the - * OS from prefilling it. - * - * If you are not reusing the idle thread's stack during startup then - * you should pass in the correct size here. - */ - status = atomOSInit(&idle_thread_stack[0], - IDLE_STACK_SIZE_BYTES, 0); - if (status == ATOM_OK) - { - arm_irq_init(); - - arm_timer_init(SYSTEM_TICKS_PER_SEC); - - arm_uart_init(); - - /* Create an application thread */ - status = atomThreadCreate(&main_tcb, - TEST_THREAD_PRIO, main_thread_func, 0, - &main_thread_stack[0], - MAIN_STACK_SIZE_BYTES, 0); - if (status == ATOM_OK) - { - arm_timer_enable(); - - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } - } - - while (1); - - /* There was an error starting the OS if we reach here */ - return (0); -} - - -/** - * \b main_thread_func - * - * Entry point for main application thread. - * - * This is the first thread that will be executed when the OS is started. - * - * @param[in] data Unused (optional thread entry parameter) - * - * @return None - */ -static void main_thread_func (uint32_t data) -{ - /* Put a message out on the UART */ - printk("Test Started ... "); - if (test_start() != 0) { - printk("FAILED!\n"); - } else { - printk("SUCCESS!\n"); - } - printk("Reset your board !!!!!"); - /* Test finished so just hang !!! */ - while (1); -} diff --git a/ports/arm7a/atomport-asm.S b/ports/arm7a/atomport-asm.S deleted file mode 100644 index 9208fc4..0000000 --- a/ports/arm7a/atomport-asm.S +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel for Atomthreads Project. - * 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 - - .section .text - -/** - * int archSetJump(pt_regs_t *regs) - */ - .globl archSetJump -archSetJump: - add r0, r0, #(4 * 16) - str lr, [r0] - sub r0, r0, #(4 * 14) - stm r0, {r1-r14} - mov r0, r0 /* NOP */ - str r2, [r1] - mov r2, #0 - sub r0, r0, #4 - str r2, [r0] - mrs r2, cpsr_all - sub r0, r0, #4 - str r2, [r0] - ldr r2, [r1] - mov r0, #1 - bx lr - -/** - * void archLongJump(pt_regs_t *regs) - */ - .globl archLongJump -archLongJump: - mrs r1, cpsr_all - SET_CURRENT_MODE CPSR_MODE_UNDEFINED - mov sp, r0 - SET_CURRENT_MODE CPSR_MODE_ABORT - mov sp, r0 - SET_CURRENT_MODE CPSR_MODE_IRQ - mov sp, r0 - SET_CURRENT_MODE CPSR_MODE_FIQ - mov sp, r0 - msr cpsr_all, r1 - ldr r1, [r0], #4 /* Get CPSR from stack */ - msr spsr_all, r1 - orr r1, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) - msr cpsr_all, r1 - ldm r0, {r0-r15}^ - mov r0, r0 /* NOP */ - diff --git a/ports/arm7a/atomport-tests.h b/ports/arm7a/atomport-tests.h deleted file mode 100644 index d76e27d..0000000 --- a/ports/arm7a/atomport-tests.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H -#define __ATOM_PORT_TESTS_H - -/* Include Atomthreads kernel API */ -#include "atom.h" - -/* Logger macro for viewing test results */ -/* FIXME: Add uart out routine once uart is supported */ -#define ATOMLOG printk -#define _STR - -/* Default thread stack size (in bytes) */ -#define TEST_THREAD_STACK_SIZE 8192 - -/* Uncomment to enable logging of stack usage to UART */ -/* #define TESTS_LOG_STACK_USAGE */ - -#endif /* __ATOM_PORT_TESTS_H */ - diff --git a/ports/arm7a/atomport.c b/ports/arm7a/atomport.c deleted file mode 100644 index de52b49..0000000 --- a/ports/arm7a/atomport.c +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel for Atomthreads Project. - * 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include -#include -#include - -/** - * This function initialises each thread's stack during creation, before the - * thread is first run. New threads are scheduled in using the same - * context-switch function used for threads which were previously scheduled - * out, therefore this function should set up a stack context which looks - * much like a thread which has been scheduled out and had its context saved. - * We fill part of the stack with those registers which are involved in the - * context switch, including appropriate stack or register contents to cause - * the thread to branch to its entry point function when it is scheduled in. - * - * Interrupts should also be enabled whenever a thread is restored, hence - * ports may wish to explicitly include the interrupt-enable register here - * which will be restored when the thread is scheduled in. Other methods - * can be used to enable interrupts, however, without explicitly storing - * it in the thread's context. - */ -void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, - void (*entry_point)(UINT32), - UINT32 entry_param) -{ - int i; - pt_regs_t *regs = (pt_regs_t *)((uint32_t)stack_top - sizeof(pt_regs_t)); - - tcb_ptr->sp_save_ptr = stack_top; - regs->cpsr = CPSR_COND_ZERO_MASK | - CPSR_ASYNC_ABORT_DISABLED | CPSR_MODE_SUPERVISOR; - regs->gpr[0] = entry_param; - for (i = 1; i < 13; i++) { - regs->gpr[i] = 0x0; - } - regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 1024; - regs->lr = (uint32_t)entry_point; - regs->pc = (uint32_t)entry_point; -} - -extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); -extern void archLongJump(pt_regs_t *regs); - -/** - * archFirstThreadRestore(ATOM_TCB *new_tcb) - * - * This function is responsible for restoring and starting the first - * thread the OS runs. It expects to find the thread context exactly - * as it would be if a context save had previously taken place on it. - * The only real difference between this and the archContextSwitch() - * routine is that there is no previous thread for which context must - * be saved. - * - * The final action this function must do is to restore interrupts. - */ -void archFirstThreadRestore(ATOM_TCB *new_tcb) -{ - pt_regs_t *regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - - sizeof(pt_regs_t)); - archLongJump(regs); -} - -/** - * Function that performs the contextSwitch. Whether its a voluntary release - * of CPU by thread or a pre-emption, under both conditions this function is - * called. The signature is as follows: - * - * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) - */ -void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) -{ - uint32_t tmp = 0x0, lr = 0x0; - pt_regs_t *old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr - - sizeof(pt_regs_t)); - pt_regs_t *new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr - - sizeof(pt_regs_t)); - asm volatile (" mov %0, lr\n\t" :"=r"(lr):); - if (archSetJump(old_regs, &tmp)) { - old_regs->lr = lr; - archLongJump(new_regs); - } -} - diff --git a/ports/arm7a/atomport.h b/ports/arm7a/atomport.h deleted file mode 100644 index 487df12..0000000 --- a/ports/arm7a/atomport.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel for Atomthreads Project. - * 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H -#define __ATOM_PORT_H - -/* Required number of system ticks per second (normally 100 for 10ms tick) */ -#define SYSTEM_TICKS_PER_SEC 1000 - -typedef signed int int32_t; -typedef signed short int16_t; -typedef signed char int8_t; -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -typedef long long int64_t; -typedef unsigned long size_t; - -typedef unsigned int irq_flags_t; -typedef unsigned int virtual_addr_t; -typedef unsigned int virtual_size_t; -typedef unsigned int physical_addr_t; -typedef unsigned int physical_size_t; -typedef unsigned int clock_freq_t; -typedef unsigned long long jiffies_t; - -#define UINT32 uint32_t -#define STACK_ALIGN_SIZE sizeof(uint32_t) -#define NULL ((void *)(0)) - -/** - * Architecture-specific types. - * Most of these are available from stdint.h on this platform, which is - * included above. - */ -#define POINTER void * - -struct pt_regs { - uint32_t cpsr; // Current Program Status - uint32_t gpr[13]; // R0 - R12 - uint32_t sp; - uint32_t lr; - uint32_t pc; -} __attribute ((packed)) ; -typedef struct pt_regs pt_regs_t; - -#include -#include - -/* Critical region protection */ -#define CRITICAL_STORE irq_flags_t status_flags -#define CRITICAL_START() status_flags = arm_irq_save(); -#define CRITICAL_END() arm_irq_restore(status_flags); - -/* Uncomment to enable stack-checking */ -/* #define ATOM_STACK_CHECKING */ - -#endif /* __ATOM_PORT_H */ diff --git a/ports/arm7a/linker.ld b/ports/arm7a/linker.ld deleted file mode 100755 index f91ed6e..0000000 --- a/ports/arm7a/linker.ld +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") -OUTPUT_ARCH("arm") -ENTRY(_start_vect) - -SECTIONS -{ - . = 0x100000; - - .text : - { - *(.expvect) - *(.text) - . = ALIGN(4); - _etext = .; - } - - .data : - { - *(.data) - . = ALIGN(4); - _edata = .; - } - - .bss : - { - *(.bss) - . = ALIGN(4); - _ebss = .; - } - - .rodata : - { - *(.rodata .rodata.*) - . = ALIGN(4); - _erodata = .; - } - - .initial_stack : - { - PROVIDE(_initial_stack_start = .); - . = . + 4096; - . = ALIGN(4); - PROVIDE(_initial_stack_end = .); - } -} diff --git a/ports/arm7a/pb-a8/Makefile b/ports/arm7a/pb-a8/Makefile deleted file mode 100644 index f44b66c..0000000 --- a/ports/arm7a/pb-a8/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -########################## -# Board specific objects # -########################## - -# board object files -objs += pb-a8/arm_pic.o -objs += pb-a8/arm_timer.o -objs += pb-a8/arm_uart.o - diff --git a/ports/arm7a/pb-a8/arm_config.h b/ports/arm7a/pb-a8/arm_config.h deleted file mode 100644 index d4e9e99..0000000 --- a/ports/arm7a/pb-a8/arm_config.h +++ /dev/null @@ -1,147 +0,0 @@ -/** - * Copyright (c) 2011 Anup Patel. - * All rights reserved. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - * @file arm_config.h - * @version 1.0 - * @author Anup Patel (anup@brainfault.org) - * @brief ARM Platform Configuration Header - */ -#ifndef _ARM_CONFIG_H__ -#define _ARM_CONFIG_H__ - -/* - * Peripheral addresses - */ -#define REALVIEW_PBA8_UART0_BASE 0x10009000 /* UART 0 */ -#define REALVIEW_PBA8_UART1_BASE 0x1000A000 /* UART 1 */ -#define REALVIEW_PBA8_UART2_BASE 0x1000B000 /* UART 2 */ -#define REALVIEW_PBA8_UART3_BASE 0x1000C000 /* UART 3 */ -#define REALVIEW_PBA8_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ -#define REALVIEW_PBA8_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ -#define REALVIEW_PBA8_WATCHDOG_BASE 0x10010000 /* watchdog interface */ -#define REALVIEW_PBA8_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ -#define REALVIEW_PBA8_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ -#define REALVIEW_PBA8_GPIO0_BASE 0x10013000 /* GPIO port 0 */ -#define REALVIEW_PBA8_RTC_BASE 0x10017000 /* Real Time Clock */ -#define REALVIEW_PBA8_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ -#define REALVIEW_PBA8_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ -#define REALVIEW_PBA8_SCTL_BASE 0x1001A000 /* System Controller */ -#define REALVIEW_PBA8_CLCD_BASE 0x10020000 /* CLCD */ -#define REALVIEW_PBA8_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ -#define REALVIEW_PBA8_DMC_BASE 0x100E0000 /* DMC configuration */ -#define REALVIEW_PBA8_SMC_BASE 0x100E1000 /* SMC configuration */ -#define REALVIEW_PBA8_CAN_BASE 0x100E2000 /* CAN bus */ -#define REALVIEW_PBA8_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */ -#define REALVIEW_PBA8_FLASH0_BASE 0x40000000 -#define REALVIEW_PBA8_FLASH0_SIZE SZ_64M -#define REALVIEW_PBA8_FLASH1_BASE 0x44000000 -#define REALVIEW_PBA8_FLASH1_SIZE SZ_64M -#define REALVIEW_PBA8_ETH_BASE 0x4E000000 /* Ethernet */ -#define REALVIEW_PBA8_USB_BASE 0x4F000000 /* USB */ -#define REALVIEW_PBA8_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ -#define REALVIEW_PBA8_LT_BASE 0xC0000000 /* Logic Tile expansion */ -#define REALVIEW_PBA8_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ -#define REALVIEW_PBA8_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ - -#define REALVIEW_PBA8_SYS_PLD_CTRL1 0x74 - -/* - * PBA8 PCI regions - */ -#define REALVIEW_PBA8_PCI_BASE 0x90040000 /* PCI-X Unit base */ -#define REALVIEW_PBA8_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ -#define REALVIEW_PBA8_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ - -#define REALVIEW_PBA8_PCI_BASE_SIZE 0x10000 /* 16 Kb */ -#define REALVIEW_PBA8_PCI_IO_SIZE 0x1000 /* 4 Kb */ -#define REALVIEW_PBA8_PCI_MEM_SIZE 0x20000000 /* 512 MB */ - -/* - * Irqs - */ -#define IRQ_PBA8_GIC_START 32 - -/* L220 -#define IRQ_PBA8_L220_EVENT (IRQ_PBA8_GIC_START + 29) -#define IRQ_PBA8_L220_SLAVE (IRQ_PBA8_GIC_START + 30) -#define IRQ_PBA8_L220_DECODE (IRQ_PBA8_GIC_START + 31) -*/ - -/* - * PB-A8 on-board gic irq sources - */ -#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ -#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ -#define IRQ_PBA8_COMMRx (IRQ_PBA8_GIC_START + 2) /* Debug Comm Rx interrupt */ -#define IRQ_PBA8_COMMTx (IRQ_PBA8_GIC_START + 3) /* Debug Comm Tx interrupt */ -#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 4) /* Timer 0/1 (default timer) */ -#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 5) /* Timer 2/3 */ -#define IRQ_PBA8_GPIO0 (IRQ_PBA8_GIC_START + 6) /* GPIO 0 */ -#define IRQ_PBA8_GPIO1 (IRQ_PBA8_GIC_START + 7) /* GPIO 1 */ -#define IRQ_PBA8_GPIO2 (IRQ_PBA8_GIC_START + 8) /* GPIO 2 */ - /* 9 reserved */ -#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 10) /* Real Time Clock */ -#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ -#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 12) /* UART 0 on development chip */ -#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 13) /* UART 1 on development chip */ -#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 14) /* UART 2 on development chip */ -#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 15) /* UART 3 on development chip */ -#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ -#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ -#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ -#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ -#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ -#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ -#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ -#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ -#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ -#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ -#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ -#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ -#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ -#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ -#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ -#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ - -/* ... */ -#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) -#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) -#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) -#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) - -#define IRQ_PBA8_SMC -1 -#define IRQ_PBA8_SCTL -1 - -#define NR_GIC_PBA8 1 - -/* - * Only define NR_IRQS if less than NR_IRQS_PBA8 - */ -#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) - -#if !defined(ARM_GIC_NR_IRQS) || (ARM_GIC_NR_IRQS < NR_IRQS_PBA8) -#undef ARM_GIC_NR_IRQS -#define ARM_GIC_NR_IRQS NR_IRQS_PBA8 -#endif - -#if !defined(ARM_GIC_MAX_NR) || (REALVIEW_GIC_MAX_NR < NR_GIC_PBA8) -#undef ARM_GIC_MAX_NR -#define ARM_GIC_MAX_NR NR_GIC_PBA8 -#endif - -#endif diff --git a/ports/arm7a/pb-a8/arm_pic.c b/ports/arm7a/pb-a8/arm_pic.c deleted file mode 100644 index d17ef1b..0000000 --- a/ports/arm7a/pb-a8/arm_pic.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include -#include - -#define max(a,b) ((a) < (b) ? (b) : (a)) - -struct gic_chip_data { - uint32_t irq_offset; - virtual_addr_t dist_base; - virtual_addr_t cpu_base; -}; - -static struct gic_chip_data gic_data[ARM_GIC_MAX_NR]; - -static inline void arm_gic_write(uint32_t val, virtual_addr_t addr) -{ - arm_writel(val, (void *)(addr)); -} - -static inline uint32_t arm_gic_read(virtual_addr_t addr) -{ - return arm_readl((void *)(addr)); -} - -int arm_gic_active_irq(uint32_t gic_nr) -{ - int ret = -1; - - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - ret = arm_gic_read(gic_data[gic_nr].cpu_base + - GIC_CPU_INTACK) & 0x3FF; - ret += gic_data[gic_nr].irq_offset; - - return ret; -} - -int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq) -{ - uint32_t mask = 1 << (irq % 32); - uint32_t gic_irq; - - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - if (irq < gic_data[gic_nr].irq_offset) { - return -1; - } - - gic_irq = irq - gic_data[gic_nr].irq_offset; - - arm_gic_write(mask, gic_data[gic_nr].dist_base + - GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); - arm_gic_write(gic_irq, gic_data[gic_nr].cpu_base + GIC_CPU_EOI); - arm_gic_write(mask, gic_data[gic_nr].dist_base + - GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); - - return 0; -} - -int arm_gic_mask(uint32_t gic_nr, uint32_t irq) -{ - uint32_t mask = 1 << (irq % 32); - uint32_t gic_irq; - - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - if (irq < gic_data[gic_nr].irq_offset) { - return -1; - } - - gic_irq = irq - gic_data[gic_nr].irq_offset; - - arm_gic_write(mask, gic_data[gic_nr].dist_base + - GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); - - return 0; -} - -int arm_gic_unmask(uint32_t gic_nr, uint32_t irq) -{ - uint32_t mask = 1 << (irq % 32); - uint32_t gic_irq; - - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - if (irq < gic_data[gic_nr].irq_offset) { - return -1; - } - - gic_irq = irq - gic_data[gic_nr].irq_offset; - - arm_gic_write(mask, gic_data[gic_nr].dist_base + - GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); - - return 0; -} - -int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start) -{ - unsigned int max_irq, i; - uint32_t cpumask = 1 << 0; /*smp_processor_id(); */ - - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - cpumask |= cpumask << 8; - cpumask |= cpumask << 16; - - gic_data[gic_nr].dist_base = base; - gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; - - arm_gic_write(0, base + GIC_DIST_CTRL); - - /* - * Find out how many interrupts are supported. - */ - max_irq = arm_gic_read(base + GIC_DIST_CTR) & 0x1f; - max_irq = (max_irq + 1) * 32; - - /* - * The GIC only supports up to 1020 interrupt sources. - * Limit this to either the architected maximum, or the - * platform maximum. - */ - if (max_irq > max(1020, ARM_GIC_NR_IRQS)) - max_irq = max(1020, ARM_GIC_NR_IRQS); - - /* - * Set all global interrupts to be level triggered, active low. - */ - for (i = 32; i < max_irq; i += 16) - arm_gic_write(0, base + GIC_DIST_CONFIG + i * 4 / 16); - - /* - * Set all global interrupts to this CPU only. - */ - for (i = 32; i < max_irq; i += 4) - arm_gic_write(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); - - /* - * Set priority on all interrupts. - */ - for (i = 0; i < max_irq; i += 4) - arm_gic_write(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); - - /* - * Disable all interrupts. - */ - for (i = 0; i < max_irq; i += 32) - arm_gic_write(0xffffffff, - base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); - - arm_gic_write(1, base + GIC_DIST_CTRL); - - return 0; -} - -int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base) -{ - if (ARM_GIC_MAX_NR <= gic_nr) { - return -1; - } - - gic_data[gic_nr].cpu_base = base; - - arm_gic_write(0xf0, base + GIC_CPU_PRIMASK); - arm_gic_write(1, base + GIC_CPU_CTRL); - - return 0; -} - -int arm_pic_active_irq(void) -{ - return arm_gic_active_irq(0); -} - -int arm_pic_ack_irq(uint32_t irq) -{ - return arm_gic_ack_irq(0, irq); -} - -int arm_pic_mask(uint32_t irq) -{ - return arm_gic_mask(0, irq); -} - -int arm_pic_unmask(uint32_t irq) -{ - return arm_gic_unmask(0, irq); -} - -int arm_pic_init(void) -{ - int rc = 0; - - rc = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, - IRQ_PBA8_GIC_START); - if (rc) { - return rc; - } - rc = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); - if (rc) { - while(1); - } - - return rc; -} - - diff --git a/ports/arm7a/pb-a8/arm_pic.h b/ports/arm7a/pb-a8/arm_pic.h deleted file mode 100644 index d3485f0..0000000 --- a/ports/arm7a/pb-a8/arm_pic.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_GIC_H__ -#define _ARM_GIC_H__ - -#include -#include - -#define GIC_CPU_CTRL 0x00 -#define GIC_CPU_PRIMASK 0x04 -#define GIC_CPU_BINPOINT 0x08 -#define GIC_CPU_INTACK 0x0c -#define GIC_CPU_EOI 0x10 -#define GIC_CPU_RUNNINGPRI 0x14 -#define GIC_CPU_HIGHPRI 0x18 - -#define GIC_DIST_CTRL 0x000 -#define GIC_DIST_CTR 0x004 -#define GIC_DIST_ENABLE_SET 0x100 -#define GIC_DIST_ENABLE_CLEAR 0x180 -#define GIC_DIST_PENDING_SET 0x200 -#define GIC_DIST_PENDING_CLEAR 0x280 -#define GIC_DIST_ACTIVE_BIT 0x300 -#define GIC_DIST_PRI 0x400 -#define GIC_DIST_TARGET 0x800 -#define GIC_DIST_CONFIG 0xc00 -#define GIC_DIST_SOFTINT 0xf00 - -int arm_pic_active_irq(void); -int arm_pic_ack_irq(uint32_t irq); -int arm_pic_mask(uint32_t irq); -int arm_pic_unmask(uint32_t irq); -int arm_pic_init(void); - -#endif diff --git a/ports/arm7a/pb-a8/arm_plat.h b/ports/arm7a/pb-a8/arm_plat.h deleted file mode 100644 index b226955..0000000 --- a/ports/arm7a/pb-a8/arm_plat.h +++ /dev/null @@ -1,287 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_PLAT_H__ -#define _ARM_PLAT_H__ - -/* - * Memory definitions - */ -#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ -#define REALVIEW_BOOT_ROM_HI 0x30000000 -#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ -#define REALVIEW_BOOT_ROM_SIZE SZ_64M - -#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ -#define REALVIEW_SSRAM_SIZE SZ_2M - -/* - * SDRAM - */ -#define REALVIEW_SDRAM_BASE 0x00000000 - -/* - * Logic expansion modules - * - */ - -/* ------------------------------------------------------------------------ - * RealView Registers - * ------------------------------------------------------------------------ - * - */ -#define REALVIEW_SYS_ID_OFFSET 0x00 -#define REALVIEW_SYS_SW_OFFSET 0x04 -#define REALVIEW_SYS_LED_OFFSET 0x08 -#define REALVIEW_SYS_OSC0_OFFSET 0x0C - -#define REALVIEW_SYS_OSC1_OFFSET 0x10 -#define REALVIEW_SYS_OSC2_OFFSET 0x14 -#define REALVIEW_SYS_OSC3_OFFSET 0x18 -#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ - -#define REALVIEW_SYS_LOCK_OFFSET 0x20 -#define REALVIEW_SYS_100HZ_OFFSET 0x24 -#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 -#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C -#define REALVIEW_SYS_FLAGS_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 -#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 -#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 -#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C -#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 -#define REALVIEW_SYS_PCICTL_OFFSET 0x44 -#define REALVIEW_SYS_MCI_OFFSET 0x48 -#define REALVIEW_SYS_FLASH_OFFSET 0x4C -#define REALVIEW_SYS_CLCD_OFFSET 0x50 -#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 -#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 -#define REALVIEW_SYS_24MHz_OFFSET 0x5C -#define REALVIEW_SYS_MISC_OFFSET 0x60 -#define REALVIEW_SYS_IOSEL_OFFSET 0x70 -#define REALVIEW_SYS_PROCID_OFFSET 0x84 -#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 -#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 -#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 -#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC -#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 - -#define REALVIEW_SYS_BASE 0x10000000 -#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) -#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) -#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) -#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) -#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) - -#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) -#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) -#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) -#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) -#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) -#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) -#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) -#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) -#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) -#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) -#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) -#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) -#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) -#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) -#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) -#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) -#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) -#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) -#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) -#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) -#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) -#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) -#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) -#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) -#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) -#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) - -/* - * Values for REALVIEW_SYS_RESET_CTRL - */ -#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01 -#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02 -#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03 -#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04 -#define REALVIEW_SYS_CTRL_RESET_POR 0x05 -#define REALVIEW_SYS_CTRL_RESET_DoC 0x06 - -#define REALVIEW_SYS_CTRL_LED (1 << 0) - -/* ------------------------------------------------------------------------ - * RealView control registers - * ------------------------------------------------------------------------ - */ - -/* - * REALVIEW_IDFIELD - * - * 31:24 = manufacturer (0x41 = ARM) - * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) - * 15:12 = FPGA (0x3 = XVC600 or XVC600E) - * 11:4 = build value - * 3:0 = revision number (0x1 = rev B (AHB)) - */ - -/* - * REALVIEW_SYS_LOCK - * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, - * SYS_CLD, SYS_BOOTCS - */ -#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) -#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ - -/* - * REALVIEW_SYS_FLASH - */ -#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ - -/* - * REALVIEW_INTREG - * - used to acknowledge and control MMCI and UART interrupts - */ -#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ -#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ -#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ - /* write 1 to acknowledge and clear */ -#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ -#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ - -/* - * RealView common peripheral addresses - */ -#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */ -#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */ -#define REALVIEW_AACI_BASE 0x10004000 /* Audio */ -#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */ -#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */ -#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */ -#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */ -#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */ -#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */ -#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */ -#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */ -#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */ - -/* PCI space */ -#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */ -#define REALVIEW_PCI_CFG_BASE 0x42000000 -#define REALVIEW_PCI_MEM_BASE0 0x44000000 -#define REALVIEW_PCI_MEM_BASE1 0x50000000 -#define REALVIEW_PCI_MEM_BASE2 0x60000000 -/* Sizes of above maps */ -#define REALVIEW_PCI_BASE_SIZE 0x01000000 -#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000 -#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */ -#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */ -#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */ - -#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */ -#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */ - -/* - * CompactFlash - */ -#define REALVIEW_CF_BASE 0x18000000 /* CompactFlash */ -#define REALVIEW_CF_MEM_BASE 0x18003000 /* SMC for CompactFlash */ - -/* - * Disk on Chip - */ -#define REALVIEW_DOC_BASE 0x2C000000 -#define REALVIEW_DOC_SIZE (16 << 20) -#define REALVIEW_DOC_PAGE_SIZE 512 -#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE) - -#define ERASE_UNIT_PAGES 32 -#define START_PAGE 0x80 - -/* - * LED settings, bits [7:0] - */ -#define REALVIEW_SYS_LED0 (1 << 0) -#define REALVIEW_SYS_LED1 (1 << 1) -#define REALVIEW_SYS_LED2 (1 << 2) -#define REALVIEW_SYS_LED3 (1 << 3) -#define REALVIEW_SYS_LED4 (1 << 4) -#define REALVIEW_SYS_LED5 (1 << 5) -#define REALVIEW_SYS_LED6 (1 << 6) -#define REALVIEW_SYS_LED7 (1 << 7) - -#define ALL_LEDS 0xFF - -#define LED_BANK REALVIEW_SYS_LED - -/* - * Control registers - */ -#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ -#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ -#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ -#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ - -/* - * Clean base - dummy - * - */ -#define CLEAN_BASE REALVIEW_BOOT_ROM_HI - -/* - * System controller bit assignment - */ -#define REALVIEW_REFCLK 0 -#define REALVIEW_TIMCLK 1 - -#define REALVIEW_TIMER1_EnSel 15 -#define REALVIEW_TIMER2_EnSel 17 -#define REALVIEW_TIMER3_EnSel 19 -#define REALVIEW_TIMER4_EnSel 21 - -#define MAX_TIMER 2 -#define MAX_PERIOD 699050 -#define TICKS_PER_uSEC 1 - -/* - * These are useconds NOT ticks. - * - */ -#define mSEC_1 1000 -#define mSEC_5 (mSEC_1 * 5) -#define mSEC_10 (mSEC_1 * 10) -#define mSEC_25 (mSEC_1 * 25) -#define SEC_1 (mSEC_1 * 1000) - -#define REALVIEW_CSR_BASE 0x10000000 -#define REALVIEW_CSR_SIZE 0x10000000 - -#endif diff --git a/ports/arm7a/pb-a8/arm_timer.c b/ports/arm7a/pb-a8/arm_timer.c deleted file mode 100644 index e3f753f..0000000 --- a/ports/arm7a/pb-a8/arm_timer.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include -#include -#include -#include -#include -#include - -unsigned long long jiffies; - -void arm_timer_enable(void) -{ - uint32_t ctrl; - - ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - ctrl |= TIMER_CTRL_ENABLE; - arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); -} - -void arm_timer_disable(void) -{ - uint32_t ctrl; - - ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - ctrl &= ~TIMER_CTRL_ENABLE; - arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); -} - -void arm_timer_clearirq(void) -{ - arm_writel(1, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_INTCLR)); -} - -int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) -{ - /* Call the OS system tick handler */ - atomTimerTick(); - - arm_timer_clearirq(); - - return 0; -} - -int arm_timer_init(uint32_t ticks_per_sec) -{ - uint32_t val; - - /* - * set clock frequency: - * REALVIEW_TIMCLK is 1MHz - */ - val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << 0x1); - arm_writel(val, (void *)REALVIEW_SCTL_BASE); - - /* Register interrupt handler */ - arm_irq_register(IRQ_PBA8_TIMER0_1, &arm_timer_irqhndl); - - val = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - val &= ~TIMER_CTRL_ENABLE; - val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); - arm_writel(val, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); - arm_writel((1000000 / ticks_per_sec), - (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); - arm_writel((1000000 / ticks_per_sec), - (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); - - return 0; -} diff --git a/ports/arm7a/pb-a8/arm_timer.h b/ports/arm7a/pb-a8/arm_timer.h deleted file mode 100644 index 23c921c..0000000 --- a/ports/arm7a/pb-a8/arm_timer.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_TIMER_H -#define __ARM_TIMER_H - -#include - -#define TIMER_LOAD 0x00 -#define TIMER_VALUE 0x04 -#define TIMER_CTRL 0x08 -#define TIMER_CTRL_ONESHOT (1 << 0) -#define TIMER_CTRL_32BIT (1 << 1) -#define TIMER_CTRL_DIV1 (0 << 2) -#define TIMER_CTRL_DIV16 (1 << 2) -#define TIMER_CTRL_DIV256 (2 << 2) -#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ -#define TIMER_CTRL_PERIODIC (1 << 6) -#define TIMER_CTRL_ENABLE (1 << 7) - -#define TIMER_INTCLR 0x0c -#define TIMER_RIS 0x10 -#define TIMER_MIS 0x14 -#define TIMER_BGLOAD 0x18 - -void arm_timer_enable(void); -void arm_timer_disable(void); -void arm_timer_clearirq(void); -int arm_timer_init(uint32_t ticks_per_sec); - -#endif /* __ARM_TIMER_H */ diff --git a/ports/arm7a/pb-a8/arm_uart.c b/ports/arm7a/pb-a8/arm_uart.c deleted file mode 100644 index 9b423fa..0000000 --- a/ports/arm7a/pb-a8/arm_uart.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 -#include - -void arm_uart_putc(uint8_t ch) -{ - unsigned int base = 0x10009000; - if(ch=='\n') { - /* Wait until there is space in the FIFO */ - while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); - - /* Send the character */ - arm_writel('\r', (void*)(base + UART_PL01x_DR)); - } - - /* Wait until there is space in the FIFO */ - while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); - - /* Send the character */ - arm_writel(ch, (void*)(base + UART_PL01x_DR)); -} - -uint8_t arm_uart_getc(void) -{ - unsigned int base = 0x10009000; - uint8_t data; - - /* Wait until there is data in the FIFO */ - while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_RXFE); - - data = arm_readl((void*)(base + UART_PL01x_DR)); - - /* Check for an error flag */ - if (data & 0xFFFFFF00) { - /* Clear the error */ - arm_writel(0xFFFFFFFF, (void*)(base + UART_PL01x_ECR)); - return -1; - } - - return data; -} - -void arm_uart_init(void) -{ - unsigned int base = 0x10009000; - unsigned int baudrate = 115200; - unsigned int input_clock = 24000000; - unsigned int divider; - unsigned int temp; - unsigned int remainder; - unsigned int fraction; - - /* First, disable everything */ - arm_writel(0x0, (void*)(base + UART_PL011_CR)); - - /* - * Set baud rate - * - * IBRD = UART_CLK / (16 * BAUD_RATE) - * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) - * / (16 * BAUD_RATE)) - */ - temp = 16 * baudrate; - divider = input_clock / temp; - remainder = input_clock % temp; - temp = (8 * remainder) / baudrate; - fraction = (temp >> 1) + (temp & 1); - - arm_writel(divider, (void*)(base + UART_PL011_IBRD)); - arm_writel(fraction, (void*)(base + UART_PL011_FBRD)); - - /* Set the UART to be 8 bits, 1 stop bit, - * no parity, fifo enabled - */ - arm_writel((UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN), - (void*)(base + UART_PL011_LCRH)); - - /* Finally, enable the UART */ - arm_writel((UART_PL011_CR_UARTEN | - UART_PL011_CR_TXE | - UART_PL011_CR_RXE), - (void*)(base + UART_PL011_CR)); -} - diff --git a/ports/arm7a/pb-a8/arm_uart.h b/ports/arm7a/pb-a8/arm_uart.h deleted file mode 100644 index 67d47d1..0000000 --- a/ports/arm7a/pb-a8/arm_uart.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the - * Atomthreads project may be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_UART_H_ -#define __ARM_UART_H_ - -#include - -/* - * ARM PrimeCell UART's (PL010 & PL011) - * ------------------------------------ - * - * Definitions common to both PL010 & PL011 - * - */ -#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ -#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ -#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ -#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ - -#define UART_PL01x_RSR_OE 0x08 -#define UART_PL01x_RSR_BE 0x04 -#define UART_PL01x_RSR_PE 0x02 -#define UART_PL01x_RSR_FE 0x01 - -#define UART_PL01x_FR_TXFE 0x80 -#define UART_PL01x_FR_RXFF 0x40 -#define UART_PL01x_FR_TXFF 0x20 -#define UART_PL01x_FR_RXFE 0x10 -#define UART_PL01x_FR_BUSY 0x08 -#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY) - -/* - * PL011 definitions - * - */ -#define UART_PL011_IBRD 0x24 -#define UART_PL011_FBRD 0x28 -#define UART_PL011_LCRH 0x2C -#define UART_PL011_CR 0x30 -#define UART_PL011_IMSC 0x38 -#define UART_PL011_PERIPH_ID0 0xFE0 - -#define UART_PL011_LCRH_SPS (1 << 7) -#define UART_PL011_LCRH_WLEN_8 (3 << 5) -#define UART_PL011_LCRH_WLEN_7 (2 << 5) -#define UART_PL011_LCRH_WLEN_6 (1 << 5) -#define UART_PL011_LCRH_WLEN_5 (0 << 5) -#define UART_PL011_LCRH_FEN (1 << 4) -#define UART_PL011_LCRH_STP2 (1 << 3) -#define UART_PL011_LCRH_EPS (1 << 2) -#define UART_PL011_LCRH_PEN (1 << 1) -#define UART_PL011_LCRH_BRK (1 << 0) - -#define UART_PL011_CR_CTSEN (1 << 15) -#define UART_PL011_CR_RTSEN (1 << 14) -#define UART_PL011_CR_OUT2 (1 << 13) -#define UART_PL011_CR_OUT1 (1 << 12) -#define UART_PL011_CR_RTS (1 << 11) -#define UART_PL011_CR_DTR (1 << 10) -#define UART_PL011_CR_RXE (1 << 9) -#define UART_PL011_CR_TXE (1 << 8) -#define UART_PL011_CR_LPE (1 << 7) -#define UART_PL011_CR_IIRLP (1 << 2) -#define UART_PL011_CR_SIREN (1 << 1) -#define UART_PL011_CR_UARTEN (1 << 0) - -#define UART_PL011_IMSC_OEIM (1 << 10) -#define UART_PL011_IMSC_BEIM (1 << 9) -#define UART_PL011_IMSC_PEIM (1 << 8) -#define UART_PL011_IMSC_FEIM (1 << 7) -#define UART_PL011_IMSC_RTIM (1 << 6) -#define UART_PL011_IMSC_TXIM (1 << 5) -#define UART_PL011_IMSC_RXIM (1 << 4) -#define UART_PL011_IMSC_DSRMIM (1 << 3) -#define UART_PL011_IMSC_DCDMIM (1 << 2) -#define UART_PL011_IMSC_CTSMIM (1 << 1) -#define UART_PL011_IMSC_RIMIM (1 << 0) - -uint8_t arm_uart_getc(void); -void arm_uart_putc(uint8_t ch); -void arm_uart_init(void); - -#endif /* __ARM_UART_H_ */ diff --git a/ports/arm7a/printk.c b/ports/arm7a/printk.c deleted file mode 100644 index 99d137f..0000000 --- a/ports/arm7a/printk.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (c) Himanshu Chauhan 2009-11. - * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -#include -#include -#include - -static int8_t buf[2048]; - -/* Uses the above routine to output a string... */ -void puts(const uint8_t *text) -{ - int32_t i; - - for (i = 0; i < strlen((const int8_t *)text); i++) { - arm_uart_putc(text[i]); - } -} - -void printk(const char *format, ...) -{ - va_list args; - int i; - - va_start(args, format); - i = vsprintf(buf, (const int8_t *)format, args); - va_end(args); - - puts((const uint8_t *)buf); -} - diff --git a/ports/arm7a/printk.h b/ports/arm7a/printk.h deleted file mode 100644 index bd1b192..0000000 --- a/ports/arm7a/printk.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * This file is part of Freax kernel. - * - * Copyright (c) Himanshu Chauhan 2009-10. - * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H -#define _PRINTK_H - -#include "atomport.h" - -extern void putch (uint8_t ch); -extern void puts (const uint8_t *text); -extern void printk (const char*format, ...); - -#endif diff --git a/ports/arm7a/stdarg.h b/ports/arm7a/stdarg.h deleted file mode 100755 index fd79ec0..0000000 --- a/ports/arm7a/stdarg.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef _STDARG_H -#define _STDARG_H - -typedef char *va_list; - -/* Amount of space required in an argument list for an arg of type TYPE. - TYPE may alternatively be an expression whose type is used. */ - -#define __va_rounded_size(TYPE) \ - (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) - -#ifndef __sparc__ -#define va_start(AP, LASTARG) \ - (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) -#else -#define va_start(AP, LASTARG) \ - (__builtin_saveregs (), \ - AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) -#endif - -void va_end (va_list); /* Defined in gnulib */ -#define va_end(AP) - -#define va_arg(AP, TYPE) \ - (AP += __va_rounded_size (TYPE), \ - *((TYPE *) (AP - __va_rounded_size (TYPE)))) - -#endif /* _STDARG_H */ diff --git a/ports/arm7a/string.c b/ports/arm7a/string.c deleted file mode 100644 index b99b529..0000000 --- a/ports/arm7a/string.c +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) Himanshu Chauhan 2009-11. - * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 -#include - -void *memcpy(void *dest, const void *src, size_t count) -{ - const int8_t *sp = (const int8_t *)src; - int8_t *dp = (int8_t *)dest; - for(; count != 0; count--) *dp++ = *sp++; - return dest; -} - -void *memset(void *dest, int8_t val, size_t count) -{ - int8_t *temp = (int8_t *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - -uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) -{ - uint16_t *temp = (uint16_t *)dest; - for( ; count != 0; count--) *temp++ = val; - return dest; -} - -size_t strlen(const int8_t *str) -{ - size_t retval; - for(retval = 0; *str != '\0'; str++) retval++; - return retval; -} diff --git a/ports/arm7a/string.h b/ports/arm7a/string.h deleted file mode 100644 index bbccc25..0000000 --- a/ports/arm7a/string.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright (c) Himanshu Chauhan 2009-11. - * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H -#define __STRING_H - -#include - -void *memcpy(void *dest, const void *src, size_t count); -void *memset(void *dest, int8_t val, size_t count); -uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); -size_t strlen(const int8_t *str); - -#endif /* __STRING_H */ - diff --git a/ports/arm7a/system.h b/ports/arm7a/system.h deleted file mode 100644 index b8c25ad..0000000 --- a/ports/arm7a/system.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) Himanshu Chauhan 2009-11. - * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H -#define _SYSTEM_H - -#include -#include - -extern const uint8_t *kernel_name; -extern const uint8_t *kernel_version; -extern const uint8_t *kernel_bdate; -extern const uint8_t *kernel_btime; - -extern void *memcpy (void *dest, const void *src, size_t count); -extern void *memset (void *dest, int8_t val, size_t count); -extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); -extern size_t strlen (const int8_t *str); -extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); -extern void init_console (void); -extern int32_t arch_init (void); -extern uint8_t ioreadb (void *addr); -extern void iowriteb (void *addr, uint8_t data); - -#endif /* _SYSTEM_H */ diff --git a/ports/arm7a/vsprintf.c b/ports/arm7a/vsprintf.c deleted file mode 100644 index c8819fd..0000000 --- a/ports/arm7a/vsprintf.c +++ /dev/null @@ -1,244 +0,0 @@ -/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ -/* - * Wirzenius wrote this portably, Torvalds fucked it up :-) - * and Himanshu Fucked it up further :)) - */ - -#include -#include -#include - -/* we use this so that we can do without the ctype library */ -#define is_digit(c) ((c) >= '0' && (c) <= '9') - -static int skip_atoi(const int8_t **s) -{ - int i=0; - - while (is_digit(**s)) - i = i*10 + *((*s)++) - '0'; - return i; -} - -#define ZEROPAD 1 /* pad with zero */ -#define SIGN 2 /* unsigned/signed long */ -#define PLUS 4 /* show plus */ -#define SPACE 8 /* space if plus */ -#define LEFT 16 /* left justified */ -#define SPECIAL 32 /* 0x */ -#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ - -/*#define do_div(n,base) ({ \ -int __res; \ -__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ -__res; })*/ - -static uint32_t do_div (int32_t *n, int32_t base) -{ - uint32_t remainder = *n % base; - *n /= base; - return remainder; -} - -static int8_t * number(int8_t * str, int num, int32_t base, - int32_t size, int32_t precision, int32_t type) -{ - int8_t c,sign,tmp[36]; - const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; - int32_t i; - - if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; - if (type & LEFT) type &= ~ZEROPAD; - if (base < 2 || base > 36) - return 0; - c = (type & ZEROPAD) ? '0' : ' ' ; - if (type & SIGN && num < 0) { - sign = '-'; - num = -num; - } else - sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); - if (sign) size--; - - if (type & SPECIAL) { - if (base == 16) { - size -= 2; - } else if (base == 8) { - size--; - } - } - - i = 0; - if (num == 0) - tmp[i++] = '0'; - else while (num != 0) - tmp[i++] = digits[do_div(&num,base)]; - if (i > precision) precision = i; - size -= precision; - if (!(type & (ZEROPAD + LEFT))) - while(size-- > 0) - *str++ = ' '; - if (sign) - *str++ = sign; - if (type & SPECIAL) { - if (base == 8) { - *str++ = '0'; - } else if (base == 16) { - *str++ = '0'; - *str++ = digits[33]; - } - } - - if (!(type & LEFT)) - while(size-- > 0) - *str++ = c; - while(i < precision--) - *str++ = '0'; - while(i-- > 0) - *str++ = tmp[i]; - while(size-- > 0) - *str++ = ' '; - return str; -} - -int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args) -{ - int32_t len; - int32_t i; - int8_t * str; - int8_t *s; - int32_t *ip; - - int32_t flags; /* flags to number() */ - - int32_t field_width; /* width of output field */ - int32_t precision; /* min. # of digits for integers; max - number of chars for from string */ - int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ - - for (str=buf ; *fmt ; ++fmt) { - if (*fmt != '%') { - *str++ = *fmt; - continue; - } - - /* process flags */ - flags = 0; - repeat: - ++fmt; /* this also skips first '%' */ - switch (*fmt) { - case '-': flags |= LEFT; goto repeat; - case '+': flags |= PLUS; goto repeat; - case ' ': flags |= SPACE; goto repeat; - case '#': flags |= SPECIAL; goto repeat; - case '0': flags |= ZEROPAD; goto repeat; - } - - /* get field width */ - field_width = -1; - if (is_digit(*fmt)) - field_width = skip_atoi(&fmt); - else if (*fmt == '*') { - /* it's the next argument */ - field_width = va_arg(args, int); - if (field_width < 0) { - field_width = -field_width; - flags |= LEFT; - } - } - - /* get the precision */ - precision = -1; - if (*fmt == '.') { - ++fmt; - if (is_digit(*fmt)) - precision = skip_atoi(&fmt); - else if (*fmt == '*') { - /* it's the next argument */ - precision = va_arg(args, int); - } - if (precision < 0) - precision = 0; - } - - /* get the conversion qualifier */ - qualifier = -1; - if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { - qualifier = *fmt; - ++fmt; - } - - switch (*fmt) { - case 'c': - if (!(flags & LEFT)) - while (--field_width > 0) - *str++ = ' '; - *str++ = (unsigned char) va_arg(args, int); - while (--field_width > 0) - *str++ = ' '; - break; - - case 's': - s = va_arg(args, int8_t *); - len = strlen(s); - if (precision < 0) - precision = len; - else if (len > precision) - len = precision; - - if (!(flags & LEFT)) - while (len < field_width--) - *str++ = ' '; - for (i = 0; i < len; ++i) - *str++ = *s++; - while (len < field_width--) - *str++ = ' '; - break; - - case 'o': - str = number(str, va_arg(args, unsigned long), 8, - field_width, precision, flags); - break; - - case 'p': - if (field_width == -1) { - field_width = 8; - flags |= ZEROPAD; - } - str = number(str, - (unsigned long) va_arg(args, void *), 16, - field_width, precision, flags); - break; - - case 'x': - flags |= SMALL; - case 'X': - str = number(str, va_arg(args, unsigned long), 16, - field_width, precision, flags); - break; - - case 'd': - case 'i': - flags |= SIGN; - case 'u': - str = number(str, va_arg(args, unsigned long), 10, - field_width, precision, flags); - break; - - case 'n': - ip = va_arg(args, int32_t *); - *ip = (str - buf); - break; - - default: - if (*fmt != '%') - *str++ = '%'; - if (*fmt) - *str++ = *fmt; - else - --fmt; - break; - } - } - *str = '\0'; - return str-buf; -} From f36452df66105f5b4b25b16603b7ee2bbb30ae26 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Thu, 7 Jul 2011 17:37:12 +0530 Subject: [PATCH 54/76] Adding file to armv7a directory. Signed-off-by: Anup Patel --- ports/armv7a/Doxyfile | 1161 +++++++++++++++++++++++++++++++ ports/armv7a/Makefile | 138 ++++ ports/armv7a/arm_asm_macro.h | 123 ++++ ports/armv7a/arm_defines.h | 68 ++ ports/armv7a/arm_entry.S | 151 ++++ ports/armv7a/arm_io.h | 45 ++ ports/armv7a/arm_irq.c | 201 ++++++ ports/armv7a/arm_irq.h | 57 ++ ports/armv7a/arm_main.c | 231 ++++++ ports/armv7a/atomport-asm.S | 77 ++ ports/armv7a/atomport-tests.h | 48 ++ ports/armv7a/atomport.c | 113 +++ ports/armv7a/atomport.h | 85 +++ ports/armv7a/linker.ld | 74 ++ ports/armv7a/pb-a8/Makefile | 9 + ports/armv7a/pb-a8/arm_config.h | 147 ++++ ports/armv7a/pb-a8/arm_pic.c | 247 +++++++ ports/armv7a/pb-a8/arm_pic.h | 61 ++ ports/armv7a/pb-a8/arm_plat.h | 287 ++++++++ ports/armv7a/pb-a8/arm_timer.c | 97 +++ ports/armv7a/pb-a8/arm_timer.h | 56 ++ ports/armv7a/pb-a8/arm_uart.c | 112 +++ ports/armv7a/pb-a8/arm_uart.h | 110 +++ ports/armv7a/printk.c | 59 ++ ports/armv7a/printk.h | 42 ++ ports/armv7a/stdarg.h | 28 + ports/armv7a/string.c | 61 ++ ports/armv7a/string.h | 42 ++ ports/armv7a/system.h | 52 ++ ports/armv7a/vsprintf.c | 244 +++++++ 30 files changed, 4226 insertions(+) create mode 100644 ports/armv7a/Doxyfile create mode 100644 ports/armv7a/Makefile create mode 100644 ports/armv7a/arm_asm_macro.h create mode 100644 ports/armv7a/arm_defines.h create mode 100644 ports/armv7a/arm_entry.S create mode 100644 ports/armv7a/arm_io.h create mode 100644 ports/armv7a/arm_irq.c create mode 100644 ports/armv7a/arm_irq.h create mode 100644 ports/armv7a/arm_main.c create mode 100644 ports/armv7a/atomport-asm.S create mode 100644 ports/armv7a/atomport-tests.h create mode 100644 ports/armv7a/atomport.c create mode 100644 ports/armv7a/atomport.h create mode 100755 ports/armv7a/linker.ld create mode 100644 ports/armv7a/pb-a8/Makefile create mode 100644 ports/armv7a/pb-a8/arm_config.h create mode 100644 ports/armv7a/pb-a8/arm_pic.c create mode 100644 ports/armv7a/pb-a8/arm_pic.h create mode 100644 ports/armv7a/pb-a8/arm_plat.h create mode 100644 ports/armv7a/pb-a8/arm_timer.c create mode 100644 ports/armv7a/pb-a8/arm_timer.h create mode 100644 ports/armv7a/pb-a8/arm_uart.c create mode 100644 ports/armv7a/pb-a8/arm_uart.h create mode 100644 ports/armv7a/printk.c create mode 100644 ports/armv7a/printk.h create mode 100755 ports/armv7a/stdarg.h create mode 100644 ports/armv7a/string.c create mode 100644 ports/armv7a/string.h create mode 100644 ports/armv7a/system.h create mode 100644 ports/armv7a/vsprintf.c diff --git a/ports/armv7a/Doxyfile b/ports/armv7a/Doxyfile new file mode 100644 index 0000000..e6f6571 --- /dev/null +++ b/ports/armv7a/Doxyfile @@ -0,0 +1,1161 @@ +# Doxyfile 1.3.9.1 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = atomthreads + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = doxygen-avr + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of source +# files, where putting all generated files in the same directory would otherwise +# cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Brazilian, Catalan, Chinese, Chinese-Traditional, Croatian, Czech, Danish, +# Dutch, Finnish, French, German, Greek, Hungarian, Italian, Japanese, +# Japanese-en (Japanese with English messages), Korean, Korean-en, Norwegian, +# Polish, Portuguese, Romanian, Russian, Serbian, Slovak, Slovene, Spanish, +# Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is used +# as the annotated text. Otherwise, the brief description is used as-is. If left +# blank, the following values are used ("$name" is automatically replaced with the +# name of the entity): "The $name class" "The $name widget" "The $name file" +# "is" "provides" "specifies" "contains" "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all inherited +# members of a class in the documentation of that class as if those members were +# ordinary class members. Constructors, destructors and assignment operators of +# the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = YES + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 4 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources +# only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java sources +# only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = YES + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = YES + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. + +SHOW_DIRECTORIES = YES + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = NO + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +WARN_IF_UNDOCUMENTED = YES + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx *.hpp +# *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or directories +# that are symbolic links (a Unix filesystem feature) are excluded from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = html + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_PREDEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse the +# parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base or +# super classes. Setting the tag to NO turns the diagrams off. Note that this +# option is superseded by the HAVE_DOT option below. This is only a fallback. It is +# recommended to install and use dot, since it yields more powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = NO + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found on the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes that +# lay further from the root node will be omitted. Note that setting this option to +# 1 or 2 may greatly reduce the computation time needed for large code bases. Also +# note that a graph may be further truncated if the graph's image dimensions are +# not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH and MAX_DOT_GRAPH_HEIGHT). +# If 0 is used for the depth value (the default), the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO diff --git a/ports/armv7a/Makefile b/ports/armv7a/Makefile new file mode 100644 index 0000000..a066851 --- /dev/null +++ b/ports/armv7a/Makefile @@ -0,0 +1,138 @@ +########################################## +# Toplevel makefile for all ARM7a boards # +########################################## + +# Build directory +ifdef O + build_dir=$(shell readlink -f $(O)) +else + build_dir=$(CURDIR)/build +endif + +# Source directory +src_dir=$(CURDIR) + +# Configuration +CPU=cortex-a8 +BOARD=pb-a8 +CC=$(CROSS_COMPILE)gcc +OBJCOPY=$(CROSS_COMPILE)objcopy +# Enable stack-checking. WARNING: the full automated test suite currently +# requires a little over 1KB RAM with stack-checking enabled. If you are +# using a device with 1KB internal SRAM and no external SRAM then you +# must disable stack-checking to run all of the automated tests. +#STACK_CHECK=true + +# Location of atomthreads sources +board_dir=$(src_dir)/$(BOARD) +kernel_dir=$(src_dir)/../../kernel +tests_dir=$(src_dir)/../../tests + +# Check if verbosity is ON for build process +VERBOSE_DEFAULT := 0 +CMD_PREFIX_DEFAULT := @ +ifdef VERBOSE + ifeq ("$(origin VERBOSE)", "command line") + VB := $(VERBOSE) + else + VB := $(VERBOSE_DEFAULT) + endif +else + VB := $(VERBOSE_DEFAULT) +endif +ifeq ($(VB), 1) + V := +else + V := $(CMD_PREFIX_DEFAULT) +endif + +# object files +objs = arm_irq.o +objs += arm_main.o +objs += atomport.o +objs += arm_entry.o +objs += atomport-asm.o + +# include board makefile for board specific objects +-include $(board_dir)/Makefile + +# library object files +objs += printk.o +objs += string.o +objs += vsprintf.o + +# Kernel object files +objs += atomkernel.o +objs += atomsem.o +objs += atommutex.o +objs += atomtimer.o +objs += atomqueue.o + +# Collection of built objects (excluding test applications) +build_objs = $(foreach obj,$(objs),$(build_dir)/$(obj)) + +# Target application filenames .elf for each test object +tobjs = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) +telfs = $(patsubst %.o,%.elf,$(tobjs)) +build_tobjs = $(foreach tobj,$(tobjs),$(build_dir)/$(tobj)) +build_telfs = $(foreach telf,$(telfs),$(build_dir)/$(telf)) + +# GCC flags +CFLAGS= -g \ + -Wall \ + -Werror \ + -mcpu=$(CPU) \ + -nostdinc \ + -nostdlib \ + -nodefaultlibs \ + -fno-builtin \ + -I$(src_dir) \ + -I$(board_dir) \ + -I$(kernel_dir) \ + -I$(tests_dir) + +# Enable stack-checking (disable if not required) +ifeq ($(STACK_CHECK),true) +CFLAGS += -DATOM_STACK_CHECKING +endif + +# All +.PHONY: all +all: $(build_telfs) $(build_tobjs) $(build_objs) Makefile + +$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T linker.ld -o $@ + +$(build_dir)/%.o: $(src_dir)/%.S + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (AS) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) -D__ASSEMBLY__ -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(src_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(kernel_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +$(build_dir)/%.o: $(tests_dir)/%.c + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (CC) $(subst $(build_dir)/,,$@)") + $(V)$(CC) $(CFLAGS) $(CFLAGS) -I`dirname $<` -c $< -o $@ + +# Clean +.PHONY: clean +clean: + rm -rf doxygen-kernel + rm -rf doxygen-avr + rm -rf $(build_dir) +# Docs +.PHONY: doxygen +doxygen: + doxygen $(kernel_dir)/Doxyfile + doxygen ./Doxyfile diff --git a/ports/armv7a/arm_asm_macro.h b/ports/armv7a/arm_asm_macro.h new file mode 100644 index 0000000..4d833b3 --- /dev/null +++ b/ports/armv7a/arm_asm_macro.h @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_ASM_MACRO_H__ +#define __ARM_ASM_MACRO_H__ + +#include + +#ifdef __ASSEMBLY__ + +.macro SET_CURRENT_FLAGS flags, treg + mrs \treg, cpsr + orr \treg, \treg, #(\flags) + msr cpsr, \treg +.endm + +.macro SET_CURRENT_MODE mode + cps #(\mode) +.endm + +.macro SET_CURRENT_STACK new_stack + ldr sp, \new_stack +.endm + +.macro START_EXCEPTION_HANDLER irqname, lroffset + .align 5 +\irqname: + sub lr, lr, #\lroffset +.endm + +/* Save User Registers */ +.macro PUSH_USER_REGS + str lr, [sp, #-4]!; /* Push the return address */ + sub sp, sp, #(4*15); /* Adjust the stack pointer */ + stmia sp, {r0-r12}; /* Push user mode registers */ + add r0, sp, #(4*13); /* Adjust the stack pointer */ + stmia r0, {r13-r14}^; /* Push user mode registers */ + mov r0, r0; /* NOP for previous inst */ + mrs r0, spsr_all; /* Put the SPSR on the stack */ + str r0, [sp, #-4]! +.endm + +/* If came from priviledged mode then push banked registers */ +.macro PUSH_BANKED_REGS skip_lable + mov r4, r0 + and r0, r0, #CPSR_MODE_MASK + cmp r0, #CPSR_MODE_USER + beq \skip_lable + add r1, sp, #(4*14) + mrs r5, cpsr + orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr, r4 + str sp, [r1, #0] + str lr, [r1, #4] + msr cpsr, r5 + \skip_lable: +.endm + +/* Call C function to handle exception */ +.macro CALL_EXCEPTION_CFUNC cfunc + mov r0, sp + bl \cfunc +.endm + +/* If going back to priviledged mode then pull banked registers */ +.macro PULL_BANKED_REGS skip_lable + ldr r0, [sp, #0] + mov r4, r0 + and r0, r0, #CPSR_MODE_MASK + cmp r0, #CPSR_MODE_USER + beq \skip_lable + add r1, sp, #(4*14) + mrs r5, cpsr + orr r4, r4, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr, r4 + ldr sp, [r1, #0] + ldr lr, [r1, #4] + msr cpsr, r5 + \skip_lable: +.endm + +/* Restore User Registers */ +.macro PULL_USER_REGS + ldr r0, [sp], #0x0004; /* Get SPSR from stack */ + msr spsr_all, r0; + ldmia sp, {r0-r14}^; /* Restore registers (user) */ + mov r0, r0; /* NOP for previous isnt */ + add sp, sp, #(4*15); /* Adjust the stack pointer */ + ldr lr, [sp], #0x0004 /* Pull return address */ +.endm + +.macro END_EXCEPTION_HANDLER + movs pc, lr +.endm + +#endif + +#endif diff --git a/ports/armv7a/arm_defines.h b/ports/armv7a/arm_defines.h new file mode 100644 index 0000000..8de737c --- /dev/null +++ b/ports/armv7a/arm_defines.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2010, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_DEFINES_H_ +#define __ARM_DEFINES_H_ + +#define CPSR_VALIDBITS_MASK 0xFF0FFFFF +#define CPSR_USERBITS_MASK 0xFFFFFC00 +#define CPSR_USERBITS_SHIFT 10 +#define CPSR_PRIVBITS_MASK 0x000003FF +#define CPSR_PRIVBITS_SHIFT 0 +#define CPSR_MODE_MASK 0x0000001f +#define CPSR_MODE_USER 0x00000010 +#define CPSR_MODE_FIQ 0x00000011 +#define CPSR_MODE_IRQ 0x00000012 +#define CPSR_MODE_SUPERVISOR 0x00000013 +#define CPSR_MODE_MONITOR 0x00000016 +#define CPSR_MODE_ABORT 0x00000017 +#define CPSR_MODE_UNDEFINED 0x0000001b +#define CPSR_MODE_SYSTEM 0x0000001f +#define CPSR_THUMB_ENABLED (1 << 5) +#define CPSR_FIQ_DISABLED (1 << 6) +#define CPSR_IRQ_DISABLED (1 << 7) +#define CPSR_ASYNC_ABORT_DISABLED (1 << 8) +#define CPSR_BE_ENABLED (1 << 9) +#define CPSR_IT2_MASK 0x0000FC00 +#define CPSR_IT2_SHIFT 10 +#define CPSR_GE_MASK 0x000F0000 +#define CPSR_GE_SHIFT 16 +#define CPSR_JAZZLE_ENABLED (1 << 24) +#define CPSR_IT1_MASK 0x06000000 +#define CPSR_IT1_SHIFT 25 +#define CPSR_COND_OVERFLOW_MASK (1 << 28) +#define CPSR_COND_OVERFLOW_SHIFT 28 +#define CPSR_COND_CARRY_MASK (1 << 29) +#define CPSR_COND_CARRY_SHIFT 29 +#define CPSR_COND_ZERO_MASK (1 << 30) +#define CPSR_COND_ZERO_SHIFT 30 +#define CPSR_COND_NEGATIVE_MASK (1 << 31) +#define CPSR_COND_NEGATIVE_SHIFT 31 + +#endif /* __ARM_DEFINES_H_ */ diff --git a/ports/armv7a/arm_entry.S b/ports/armv7a/arm_entry.S new file mode 100644 index 0000000..9f21d94 --- /dev/null +++ b/ports/armv7a/arm_entry.S @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + + .section .expvect, "ax", %progbits + .globl _start_vect +_start_vect: + ldr pc, __reset + ldr pc, __undefined_instruction + ldr pc, __software_interrupt + ldr pc, __prefetch_abort + ldr pc, __data_abort + ldr pc, __not_used + ldr pc, __irq + ldr pc, __fiq +__reset: + .word _reset +__undefined_instruction: + .word _undefined_instruction +__software_interrupt: + .word _software_interrupt +__prefetch_abort: + .word _prefetch_abort +__data_abort: + .word _data_abort +__not_used: + .word _not_used +__irq: + .word _irq +__fiq: + .word _fiq + .global _end_vect +_end_vect: + +__initial_stack_end: + .word _initial_stack_end + + .globl _reset +_reset: + /* Clear a register for temporary usage */ + mov r8, #0 + /* Disable IRQ & FIQ */ + cpsid if + /* Set Supervisor Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_SUPERVISOR + SET_CURRENT_STACK __initial_stack_end + /* Set Undefined Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_UNDEFINED + SET_CURRENT_STACK __initial_stack_end + /* Set Abort Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_ABORT + SET_CURRENT_STACK __initial_stack_end + /* Set IRQ Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_IRQ + SET_CURRENT_STACK __initial_stack_end + /* Set FIQ Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_FIQ + SET_CURRENT_STACK __initial_stack_end + /* Set System Mode Stack */ + SET_CURRENT_MODE CPSR_MODE_SYSTEM + SET_CURRENT_STACK __initial_stack_end + /* Set to Supervisor Mode */ + SET_CURRENT_MODE CPSR_MODE_SUPERVISOR + /* Call main function */ + bl main + /* We should never reach here */ + b . + +START_EXCEPTION_HANDLER _undefined_instruction, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _undefined_instruction_bankpush_skip + CALL_EXCEPTION_CFUNC do_undefined_instruction + PULL_BANKED_REGS _undefined_instruction_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _software_interrupt, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _software_interrupt_bankpush_skip + CALL_EXCEPTION_CFUNC do_software_interrupt + PULL_BANKED_REGS _software_interrupt_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _prefetch_abort, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _prefetch_abort_bankpush_skip + CALL_EXCEPTION_CFUNC do_prefetch_abort + PULL_BANKED_REGS _prefetch_abort_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _data_abort, 8 + PUSH_USER_REGS + PUSH_BANKED_REGS _data_abort_bankpush_skip + CALL_EXCEPTION_CFUNC do_data_abort + PULL_BANKED_REGS _data_abort_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _not_used, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _not_used_bankpush_skip + CALL_EXCEPTION_CFUNC do_not_used + PULL_BANKED_REGS _not_used_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _irq, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _irq_bankpush_skip + CALL_EXCEPTION_CFUNC do_irq + PULL_BANKED_REGS _irq_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + +START_EXCEPTION_HANDLER _fiq, 4 + PUSH_USER_REGS + PUSH_BANKED_REGS _fiq_bankpush_skip + CALL_EXCEPTION_CFUNC do_fiq + PULL_BANKED_REGS _fiq_bankpull_skip + PULL_USER_REGS +END_EXCEPTION_HANDLER + diff --git a/ports/armv7a/arm_io.h b/ports/armv7a/arm_io.h new file mode 100644 index 0000000..950a938 --- /dev/null +++ b/ports/armv7a/arm_io.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IO_H_ +#define __ARM_IO_H_ + +#include + +static inline uint32_t arm_readl(void * addr) +{ + return *((uint32_t *)addr); +} + +static inline void arm_writel(uint32_t data, void * addr) +{ + *((uint32_t *)addr) = data; +} + +#endif /* __ARM_IO_H_ */ diff --git a/ports/armv7a/arm_irq.c b/ports/armv7a/arm_irq.c new file mode 100644 index 0000000..cc9290d --- /dev/null +++ b/ports/armv7a/arm_irq.c @@ -0,0 +1,201 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +arm_irq_handler_t irq_hndls[NR_IRQS_PBA8]; + +void do_undefined_instruction(pt_regs_t *regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_software_interrupt(pt_regs_t *regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_prefetch_abort(pt_regs_t *regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_data_abort(pt_regs_t *regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_not_used(pt_regs_t *regs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_irq(pt_regs_t *uregs) +{ + int rc = 0; + int irq = arm_pic_active_irq(); + + /* Call the interrupt entry routine */ + atomIntEnter(); + + if (-1 < irq) { + if (irq_hndls[irq]) { + rc = irq_hndls[irq](irq, uregs); + if (rc) { + while (1); + } + } + rc = arm_pic_ack_irq(irq); + if (rc) { + while (1); + } + } + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void do_fiq(pt_regs_t *uregs) +{ + /* Call the interrupt entry routine */ + atomIntEnter(); + + /* Call the interrupt exit routine */ + atomIntExit(TRUE); +} + +void arm_irq_init(void) +{ + extern uint32_t _start_vect[]; + uint32_t *vectors = (uint32_t *)NULL; + uint32_t *vectors_data = vectors + CPU_IRQ_NR; + int vec; + + /* + * Loop through the vectors we're taking over, and copy the + * vector's insn and data word. + */ + for (vec = 0; vec < CPU_IRQ_NR; vec++) { + vectors[vec] = _start_vect[vec]; + vectors_data[vec] = _start_vect[vec+CPU_IRQ_NR]; + } + + /* + * Check if verctors are set properly + */ + for (vec = 0; vec < CPU_IRQ_NR; vec++) { + if ((vectors[vec] != _start_vect[vec]) || + (vectors_data[vec] != _start_vect[vec+CPU_IRQ_NR])) { + /* Hang */ + while(1); + } + } + + /* + * Reset irq handlers + */ + for (vec = 0; vec < NR_IRQS_PBA8; vec++) { + irq_hndls[vec] = NULL; + } + + /* + * Initialize Generic Interrupt Controller + */ + vec = arm_pic_init(); + if (vec) { + while(1); + } +} + +void arm_irq_register(uint32_t irq, arm_irq_handler_t hndl) +{ + int rc = 0; + if (irq < NR_IRQS_PBA8) { + irq_hndls[irq] = hndl; + if (irq_hndls[irq]) { + rc = arm_pic_unmask(irq); + if (rc) { + while (1); + } + } + } +} + +void arm_irq_enable(void) +{ + __asm( "cpsie if" ); +} + +void arm_irq_disable(void) +{ + __asm( "cpsid if" ); +} + +irq_flags_t arm_irq_save(void) +{ + unsigned long retval; + + asm volatile (" mrs %0, cpsr\n\t" " cpsid i" /* Syntax CPSID {, #} + * Note: This instruction is supported + * from ARM6 and above + */ + :"=r" (retval)::"memory", "cc"); + + return retval; +} + +void arm_irq_restore(irq_flags_t flags) +{ + asm volatile (" msr cpsr_c, %0"::"r" (flags) + :"memory", "cc"); +} + diff --git a/ports/armv7a/arm_irq.h b/ports/armv7a/arm_irq.h new file mode 100644 index 0000000..3defb6d --- /dev/null +++ b/ports/armv7a/arm_irq.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_IRQ_H +#define __ARM_IRQ_H + +#include +#include + +typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); + +#define CPU_IRQ_NR 8 + +/** IRQ Numbers */ +#define ARM_RESET_IRQ 0 +#define ARM_UNDEF_INST_IRQ 1 +#define ARM_SOFT_IRQ 2 +#define ARM_PREFETCH_ABORT_IRQ 3 +#define ARM_DATA_ABORT_IRQ 4 +#define ARM_NOT_USED_IRQ 5 +#define ARM_EXTERNAL_IRQ 6 +#define ARM_EXTERNAL_FIQ 7 + +void arm_irq_init(void); +void arm_irq_register(uint32_t irq_no, arm_irq_handler_t hndl); +void arm_irq_enable(void); +void arm_irq_disable(void); +irq_flags_t arm_irq_save(void); +void arm_irq_restore(irq_flags_t flags); + +#endif /* __ARM_IRQ_H */ diff --git a/ports/armv7a/arm_main.c b/ports/armv7a/arm_main.c new file mode 100644 index 0000000..5546e7d --- /dev/null +++ b/ports/armv7a/arm_main.c @@ -0,0 +1,231 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include +#include "system.h" +#include +#include +#include + +/* Constants */ + +/* + * Idle thread stack size + * + * This needs to be large enough to handle any interrupt handlers + * and callbacks called by interrupt handlers (e.g. user-created + * timer callbacks) as well as the saving of all context when + * switching away from this thread. + * + * In this case, the idle stack is allocated on the BSS via the + * idle_thread_stack[] byte array. + */ +#define IDLE_STACK_SIZE_BYTES 8192 + + +/* + * Main thread stack size + * + * Note that this is not a required OS kernel thread - you will replace + * this with your own application thread. + * + * In this case the Main thread is responsible for calling out to the + * test routines. Once a test routine has finished, the test status is + * printed out on the UART and the thread remains running in a loop + * flashing a LED. + * + * The Main thread stack generally needs to be larger than the idle + * thread stack, as not only does it need to store interrupt handler + * stack saves and context switch saves, but the application main thread + * will generally be carrying out more nested function calls and require + * stack for application code local variables etc. + * + * With all OS tests implemented to date on the AVR, the Main thread + * stack has not exceeded 198 bytes. To allow all tests to run we set + * a minimum main thread stack size of 204 bytes. This may increase in + * future as the codebase changes but for the time being is enough to + * cope with all of the automated tests. + */ +#define MAIN_STACK_SIZE_BYTES 8192 + + +/* + * Startup code stack + * + * Some stack space is required at initial startup for running the main() + * routine. This stack space is only temporarily required at first bootup + * and is no longer required as soon as the OS is started. By default + * GCC sets this to the top of RAM (RAMEND) and it grows down from there. + * Because we only need this temporarily, though, it would be wasteful to + * set aside a region at the top of RAM which is not used during runtime. + * + * What we do here is to reuse part of the idle thread's stack during + * initial startup. As soon as we enter the main() routine we move the + * stack pointer to half-way down the idle thread's stack. This is used + * temporarily while calls are made to atomOSInit(), atomThreadCreate() + * and atomOSStart(). Once the OS is started this stack area is no + * longer required, and can be used for its original purpose (for the + * idle thread's stack). + * + * This does mean, however, that we cannot monitor the stack usage of the + * idle thread. Stack usage is monitored by prefilling the stack with a + * known value, and we are obliterating some of that prefilled area by + * using it as our startup stack, so we cannot use the stack-checking API + * to get a true picture of idle thread stack usage. If you wish to + * monitor idle thread stack usage for your applications then you are + * free to use a different region for the startup stack (e.g. set aside + * an area permanently, or place it somewhere you know you can reuse + * later in the application). For the time being, this method gives us a + * simple way of reducing the memory consumption without having to add + * any special AVR-specific considerations to the automated test + * applications. + * + * This optimisation was required to allow some of the larger automated + * test modules to run on devices with 1KB of RAM. You should avoid doing + * this if you can afford to set aside 64 bytes or so, or if you are + * writing your own applications in which you have further control over + * where data is located. + */ + + +/* Local data */ + +/* Application threads' TCBs */ +static ATOM_TCB main_tcb; + +/* Main thread's stack area */ +static uint8_t main_thread_stack[MAIN_STACK_SIZE_BYTES]; + +/* Idle thread's stack area */ +static uint8_t idle_thread_stack[IDLE_STACK_SIZE_BYTES]; + +/* Forward declarations */ +static void main_thread_func (uint32_t data); + +/** + * \b main + * + * Program entry point. + * + * Sets up the AVR hardware resources (system tick timer interrupt) necessary + * for the OS to be started. Creates an application thread and starts the OS. + */ + +int main ( void ) +{ + int8_t status; + + /** + * Note: to protect OS structures and data during initialisation, + * interrupts must remain disabled until the first thread + * has been restored. They are reenabled at the very end of + * the first thread restore, at which point it is safe for a + * reschedule to take place. + */ + + /** + * Initialise the OS before creating our threads. + * + * Note that we tell the OS that the idle stack is half its actual + * size. This prevents it prefilling the bottom half with known + * values for stack-checkig purposes, which we cannot allow because + * we are temporarily using it for our own stack. The remainder will + * still be available once the OS is started, this only prevents the + * OS from prefilling it. + * + * If you are not reusing the idle thread's stack during startup then + * you should pass in the correct size here. + */ + status = atomOSInit(&idle_thread_stack[0], + IDLE_STACK_SIZE_BYTES, 0); + if (status == ATOM_OK) + { + arm_irq_init(); + + arm_timer_init(SYSTEM_TICKS_PER_SEC); + + arm_uart_init(); + + /* Create an application thread */ + status = atomThreadCreate(&main_tcb, + TEST_THREAD_PRIO, main_thread_func, 0, + &main_thread_stack[0], + MAIN_STACK_SIZE_BYTES, 0); + if (status == ATOM_OK) + { + arm_timer_enable(); + + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } + } + + while (1); + + /* There was an error starting the OS if we reach here */ + return (0); +} + + +/** + * \b main_thread_func + * + * Entry point for main application thread. + * + * This is the first thread that will be executed when the OS is started. + * + * @param[in] data Unused (optional thread entry parameter) + * + * @return None + */ +static void main_thread_func (uint32_t data) +{ + /* Put a message out on the UART */ + printk("Test Started ... "); + if (test_start() != 0) { + printk("FAILED!\n"); + } else { + printk("SUCCESS!\n"); + } + printk("Reset your board !!!!!"); + /* Test finished so just hang !!! */ + while (1); +} diff --git a/ports/armv7a/atomport-asm.S b/ports/armv7a/atomport-asm.S new file mode 100644 index 0000000..9208fc4 --- /dev/null +++ b/ports/armv7a/atomport-asm.S @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 + + .section .text + +/** + * int archSetJump(pt_regs_t *regs) + */ + .globl archSetJump +archSetJump: + add r0, r0, #(4 * 16) + str lr, [r0] + sub r0, r0, #(4 * 14) + stm r0, {r1-r14} + mov r0, r0 /* NOP */ + str r2, [r1] + mov r2, #0 + sub r0, r0, #4 + str r2, [r0] + mrs r2, cpsr_all + sub r0, r0, #4 + str r2, [r0] + ldr r2, [r1] + mov r0, #1 + bx lr + +/** + * void archLongJump(pt_regs_t *regs) + */ + .globl archLongJump +archLongJump: + mrs r1, cpsr_all + SET_CURRENT_MODE CPSR_MODE_UNDEFINED + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_ABORT + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_IRQ + mov sp, r0 + SET_CURRENT_MODE CPSR_MODE_FIQ + mov sp, r0 + msr cpsr_all, r1 + ldr r1, [r0], #4 /* Get CPSR from stack */ + msr spsr_all, r1 + orr r1, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr_all, r1 + ldm r0, {r0-r15}^ + mov r0, r0 /* NOP */ + diff --git a/ports/armv7a/atomport-tests.h b/ports/armv7a/atomport-tests.h new file mode 100644 index 0000000..d76e27d --- /dev/null +++ b/ports/armv7a/atomport-tests.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_TESTS_H +#define __ATOM_PORT_TESTS_H + +/* Include Atomthreads kernel API */ +#include "atom.h" + +/* Logger macro for viewing test results */ +/* FIXME: Add uart out routine once uart is supported */ +#define ATOMLOG printk +#define _STR + +/* Default thread stack size (in bytes) */ +#define TEST_THREAD_STACK_SIZE 8192 + +/* Uncomment to enable logging of stack usage to UART */ +/* #define TESTS_LOG_STACK_USAGE */ + +#endif /* __ATOM_PORT_TESTS_H */ + diff --git a/ports/armv7a/atomport.c b/ports/armv7a/atomport.c new file mode 100644 index 0000000..de52b49 --- /dev/null +++ b/ports/armv7a/atomport.c @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include + +/** + * This function initialises each thread's stack during creation, before the + * thread is first run. New threads are scheduled in using the same + * context-switch function used for threads which were previously scheduled + * out, therefore this function should set up a stack context which looks + * much like a thread which has been scheduled out and had its context saved. + * We fill part of the stack with those registers which are involved in the + * context switch, including appropriate stack or register contents to cause + * the thread to branch to its entry point function when it is scheduled in. + * + * Interrupts should also be enabled whenever a thread is restored, hence + * ports may wish to explicitly include the interrupt-enable register here + * which will be restored when the thread is scheduled in. Other methods + * can be used to enable interrupts, however, without explicitly storing + * it in the thread's context. + */ +void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, + void (*entry_point)(UINT32), + UINT32 entry_param) +{ + int i; + pt_regs_t *regs = (pt_regs_t *)((uint32_t)stack_top - sizeof(pt_regs_t)); + + tcb_ptr->sp_save_ptr = stack_top; + regs->cpsr = CPSR_COND_ZERO_MASK | + CPSR_ASYNC_ABORT_DISABLED | CPSR_MODE_SUPERVISOR; + regs->gpr[0] = entry_param; + for (i = 1; i < 13; i++) { + regs->gpr[i] = 0x0; + } + regs->sp = (uint32_t)stack_top - sizeof(pt_regs_t) - 1024; + regs->lr = (uint32_t)entry_point; + regs->pc = (uint32_t)entry_point; +} + +extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); +extern void archLongJump(pt_regs_t *regs); + +/** + * archFirstThreadRestore(ATOM_TCB *new_tcb) + * + * This function is responsible for restoring and starting the first + * thread the OS runs. It expects to find the thread context exactly + * as it would be if a context save had previously taken place on it. + * The only real difference between this and the archContextSwitch() + * routine is that there is no previous thread for which context must + * be saved. + * + * The final action this function must do is to restore interrupts. + */ +void archFirstThreadRestore(ATOM_TCB *new_tcb) +{ + pt_regs_t *regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + archLongJump(regs); +} + +/** + * Function that performs the contextSwitch. Whether its a voluntary release + * of CPU by thread or a pre-emption, under both conditions this function is + * called. The signature is as follows: + * + * archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) + */ +void archContextSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) +{ + uint32_t tmp = 0x0, lr = 0x0; + pt_regs_t *old_regs = (pt_regs_t *)((uint32_t)old_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + pt_regs_t *new_regs = (pt_regs_t *)((uint32_t)new_tcb->sp_save_ptr + - sizeof(pt_regs_t)); + asm volatile (" mov %0, lr\n\t" :"=r"(lr):); + if (archSetJump(old_regs, &tmp)) { + old_regs->lr = lr; + archLongJump(new_regs); + } +} + diff --git a/ports/armv7a/atomport.h b/ports/armv7a/atomport.h new file mode 100644 index 0000000..487df12 --- /dev/null +++ b/ports/armv7a/atomport.h @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2011, Anup Patel for Atomthreads Project. + * 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOM_PORT_H +#define __ATOM_PORT_H + +/* Required number of system ticks per second (normally 100 for 10ms tick) */ +#define SYSTEM_TICKS_PER_SEC 1000 + +typedef signed int int32_t; +typedef signed short int16_t; +typedef signed char int8_t; +typedef unsigned int uint32_t; +typedef unsigned short uint16_t; +typedef unsigned char uint8_t; +typedef long long int64_t; +typedef unsigned long size_t; + +typedef unsigned int irq_flags_t; +typedef unsigned int virtual_addr_t; +typedef unsigned int virtual_size_t; +typedef unsigned int physical_addr_t; +typedef unsigned int physical_size_t; +typedef unsigned int clock_freq_t; +typedef unsigned long long jiffies_t; + +#define UINT32 uint32_t +#define STACK_ALIGN_SIZE sizeof(uint32_t) +#define NULL ((void *)(0)) + +/** + * Architecture-specific types. + * Most of these are available from stdint.h on this platform, which is + * included above. + */ +#define POINTER void * + +struct pt_regs { + uint32_t cpsr; // Current Program Status + uint32_t gpr[13]; // R0 - R12 + uint32_t sp; + uint32_t lr; + uint32_t pc; +} __attribute ((packed)) ; +typedef struct pt_regs pt_regs_t; + +#include +#include + +/* Critical region protection */ +#define CRITICAL_STORE irq_flags_t status_flags +#define CRITICAL_START() status_flags = arm_irq_save(); +#define CRITICAL_END() arm_irq_restore(status_flags); + +/* Uncomment to enable stack-checking */ +/* #define ATOM_STACK_CHECKING */ + +#endif /* __ATOM_PORT_H */ diff --git a/ports/armv7a/linker.ld b/ports/armv7a/linker.ld new file mode 100755 index 0000000..f91ed6e --- /dev/null +++ b/ports/armv7a/linker.ld @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH("arm") +ENTRY(_start_vect) + +SECTIONS +{ + . = 0x100000; + + .text : + { + *(.expvect) + *(.text) + . = ALIGN(4); + _etext = .; + } + + .data : + { + *(.data) + . = ALIGN(4); + _edata = .; + } + + .bss : + { + *(.bss) + . = ALIGN(4); + _ebss = .; + } + + .rodata : + { + *(.rodata .rodata.*) + . = ALIGN(4); + _erodata = .; + } + + .initial_stack : + { + PROVIDE(_initial_stack_start = .); + . = . + 4096; + . = ALIGN(4); + PROVIDE(_initial_stack_end = .); + } +} diff --git a/ports/armv7a/pb-a8/Makefile b/ports/armv7a/pb-a8/Makefile new file mode 100644 index 0000000..f44b66c --- /dev/null +++ b/ports/armv7a/pb-a8/Makefile @@ -0,0 +1,9 @@ +########################## +# Board specific objects # +########################## + +# board object files +objs += pb-a8/arm_pic.o +objs += pb-a8/arm_timer.o +objs += pb-a8/arm_uart.o + diff --git a/ports/armv7a/pb-a8/arm_config.h b/ports/armv7a/pb-a8/arm_config.h new file mode 100644 index 0000000..d4e9e99 --- /dev/null +++ b/ports/armv7a/pb-a8/arm_config.h @@ -0,0 +1,147 @@ +/** + * Copyright (c) 2011 Anup Patel. + * All rights reserved. + * + * 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., 675 Mass Ave, Cambridge, MA 02139, USA. + * + * @file arm_config.h + * @version 1.0 + * @author Anup Patel (anup@brainfault.org) + * @brief ARM Platform Configuration Header + */ +#ifndef _ARM_CONFIG_H__ +#define _ARM_CONFIG_H__ + +/* + * Peripheral addresses + */ +#define REALVIEW_PBA8_UART0_BASE 0x10009000 /* UART 0 */ +#define REALVIEW_PBA8_UART1_BASE 0x1000A000 /* UART 1 */ +#define REALVIEW_PBA8_UART2_BASE 0x1000B000 /* UART 2 */ +#define REALVIEW_PBA8_UART3_BASE 0x1000C000 /* UART 3 */ +#define REALVIEW_PBA8_SSP_BASE 0x1000D000 /* Synchronous Serial Port */ +#define REALVIEW_PBA8_WATCHDOG0_BASE 0x1000F000 /* Watchdog 0 */ +#define REALVIEW_PBA8_WATCHDOG_BASE 0x10010000 /* watchdog interface */ +#define REALVIEW_PBA8_TIMER0_1_BASE 0x10011000 /* Timer 0 and 1 */ +#define REALVIEW_PBA8_TIMER2_3_BASE 0x10012000 /* Timer 2 and 3 */ +#define REALVIEW_PBA8_GPIO0_BASE 0x10013000 /* GPIO port 0 */ +#define REALVIEW_PBA8_RTC_BASE 0x10017000 /* Real Time Clock */ +#define REALVIEW_PBA8_TIMER4_5_BASE 0x10018000 /* Timer 4/5 */ +#define REALVIEW_PBA8_TIMER6_7_BASE 0x10019000 /* Timer 6/7 */ +#define REALVIEW_PBA8_SCTL_BASE 0x1001A000 /* System Controller */ +#define REALVIEW_PBA8_CLCD_BASE 0x10020000 /* CLCD */ +#define REALVIEW_PBA8_ONB_SRAM_BASE 0x10060000 /* On-board SRAM */ +#define REALVIEW_PBA8_DMC_BASE 0x100E0000 /* DMC configuration */ +#define REALVIEW_PBA8_SMC_BASE 0x100E1000 /* SMC configuration */ +#define REALVIEW_PBA8_CAN_BASE 0x100E2000 /* CAN bus */ +#define REALVIEW_PBA8_GIC_CPU_BASE 0x1E000000 /* Generic interrupt controller CPU interface */ +#define REALVIEW_PBA8_FLASH0_BASE 0x40000000 +#define REALVIEW_PBA8_FLASH0_SIZE SZ_64M +#define REALVIEW_PBA8_FLASH1_BASE 0x44000000 +#define REALVIEW_PBA8_FLASH1_SIZE SZ_64M +#define REALVIEW_PBA8_ETH_BASE 0x4E000000 /* Ethernet */ +#define REALVIEW_PBA8_USB_BASE 0x4F000000 /* USB */ +#define REALVIEW_PBA8_GIC_DIST_BASE 0x1E001000 /* Generic interrupt controller distributor */ +#define REALVIEW_PBA8_LT_BASE 0xC0000000 /* Logic Tile expansion */ +#define REALVIEW_PBA8_SDRAM6_BASE 0x70000000 /* SDRAM bank 6 256MB */ +#define REALVIEW_PBA8_SDRAM7_BASE 0x80000000 /* SDRAM bank 7 256MB */ + +#define REALVIEW_PBA8_SYS_PLD_CTRL1 0x74 + +/* + * PBA8 PCI regions + */ +#define REALVIEW_PBA8_PCI_BASE 0x90040000 /* PCI-X Unit base */ +#define REALVIEW_PBA8_PCI_IO_BASE 0x90050000 /* IO Region on AHB */ +#define REALVIEW_PBA8_PCI_MEM_BASE 0xA0000000 /* MEM Region on AHB */ + +#define REALVIEW_PBA8_PCI_BASE_SIZE 0x10000 /* 16 Kb */ +#define REALVIEW_PBA8_PCI_IO_SIZE 0x1000 /* 4 Kb */ +#define REALVIEW_PBA8_PCI_MEM_SIZE 0x20000000 /* 512 MB */ + +/* + * Irqs + */ +#define IRQ_PBA8_GIC_START 32 + +/* L220 +#define IRQ_PBA8_L220_EVENT (IRQ_PBA8_GIC_START + 29) +#define IRQ_PBA8_L220_SLAVE (IRQ_PBA8_GIC_START + 30) +#define IRQ_PBA8_L220_DECODE (IRQ_PBA8_GIC_START + 31) +*/ + +/* + * PB-A8 on-board gic irq sources + */ +#define IRQ_PBA8_WATCHDOG (IRQ_PBA8_GIC_START + 0) /* Watchdog timer */ +#define IRQ_PBA8_SOFT (IRQ_PBA8_GIC_START + 1) /* Software interrupt */ +#define IRQ_PBA8_COMMRx (IRQ_PBA8_GIC_START + 2) /* Debug Comm Rx interrupt */ +#define IRQ_PBA8_COMMTx (IRQ_PBA8_GIC_START + 3) /* Debug Comm Tx interrupt */ +#define IRQ_PBA8_TIMER0_1 (IRQ_PBA8_GIC_START + 4) /* Timer 0/1 (default timer) */ +#define IRQ_PBA8_TIMER2_3 (IRQ_PBA8_GIC_START + 5) /* Timer 2/3 */ +#define IRQ_PBA8_GPIO0 (IRQ_PBA8_GIC_START + 6) /* GPIO 0 */ +#define IRQ_PBA8_GPIO1 (IRQ_PBA8_GIC_START + 7) /* GPIO 1 */ +#define IRQ_PBA8_GPIO2 (IRQ_PBA8_GIC_START + 8) /* GPIO 2 */ + /* 9 reserved */ +#define IRQ_PBA8_RTC (IRQ_PBA8_GIC_START + 10) /* Real Time Clock */ +#define IRQ_PBA8_SSP (IRQ_PBA8_GIC_START + 11) /* Synchronous Serial Port */ +#define IRQ_PBA8_UART0 (IRQ_PBA8_GIC_START + 12) /* UART 0 on development chip */ +#define IRQ_PBA8_UART1 (IRQ_PBA8_GIC_START + 13) /* UART 1 on development chip */ +#define IRQ_PBA8_UART2 (IRQ_PBA8_GIC_START + 14) /* UART 2 on development chip */ +#define IRQ_PBA8_UART3 (IRQ_PBA8_GIC_START + 15) /* UART 3 on development chip */ +#define IRQ_PBA8_SCI (IRQ_PBA8_GIC_START + 16) /* Smart Card Interface */ +#define IRQ_PBA8_MMCI0A (IRQ_PBA8_GIC_START + 17) /* Multimedia Card 0A */ +#define IRQ_PBA8_MMCI0B (IRQ_PBA8_GIC_START + 18) /* Multimedia Card 0B */ +#define IRQ_PBA8_AACI (IRQ_PBA8_GIC_START + 19) /* Audio Codec */ +#define IRQ_PBA8_KMI0 (IRQ_PBA8_GIC_START + 20) /* Keyboard/Mouse port 0 */ +#define IRQ_PBA8_KMI1 (IRQ_PBA8_GIC_START + 21) /* Keyboard/Mouse port 1 */ +#define IRQ_PBA8_CHARLCD (IRQ_PBA8_GIC_START + 22) /* Character LCD */ +#define IRQ_PBA8_CLCD (IRQ_PBA8_GIC_START + 23) /* CLCD controller */ +#define IRQ_PBA8_DMAC (IRQ_PBA8_GIC_START + 24) /* DMA controller */ +#define IRQ_PBA8_PWRFAIL (IRQ_PBA8_GIC_START + 25) /* Power failure */ +#define IRQ_PBA8_PISMO (IRQ_PBA8_GIC_START + 26) /* PISMO interface */ +#define IRQ_PBA8_DoC (IRQ_PBA8_GIC_START + 27) /* Disk on Chip memory controller */ +#define IRQ_PBA8_ETH (IRQ_PBA8_GIC_START + 28) /* Ethernet controller */ +#define IRQ_PBA8_USB (IRQ_PBA8_GIC_START + 29) /* USB controller */ +#define IRQ_PBA8_TSPEN (IRQ_PBA8_GIC_START + 30) /* Touchscreen pen */ +#define IRQ_PBA8_TSKPAD (IRQ_PBA8_GIC_START + 31) /* Touchscreen keypad */ + +/* ... */ +#define IRQ_PBA8_PCI0 (IRQ_PBA8_GIC_START + 50) +#define IRQ_PBA8_PCI1 (IRQ_PBA8_GIC_START + 51) +#define IRQ_PBA8_PCI2 (IRQ_PBA8_GIC_START + 52) +#define IRQ_PBA8_PCI3 (IRQ_PBA8_GIC_START + 53) + +#define IRQ_PBA8_SMC -1 +#define IRQ_PBA8_SCTL -1 + +#define NR_GIC_PBA8 1 + +/* + * Only define NR_IRQS if less than NR_IRQS_PBA8 + */ +#define NR_IRQS_PBA8 (IRQ_PBA8_GIC_START + 64) + +#if !defined(ARM_GIC_NR_IRQS) || (ARM_GIC_NR_IRQS < NR_IRQS_PBA8) +#undef ARM_GIC_NR_IRQS +#define ARM_GIC_NR_IRQS NR_IRQS_PBA8 +#endif + +#if !defined(ARM_GIC_MAX_NR) || (REALVIEW_GIC_MAX_NR < NR_GIC_PBA8) +#undef ARM_GIC_MAX_NR +#define ARM_GIC_MAX_NR NR_GIC_PBA8 +#endif + +#endif diff --git a/ports/armv7a/pb-a8/arm_pic.c b/ports/armv7a/pb-a8/arm_pic.c new file mode 100644 index 0000000..d17ef1b --- /dev/null +++ b/ports/armv7a/pb-a8/arm_pic.c @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include + +#define max(a,b) ((a) < (b) ? (b) : (a)) + +struct gic_chip_data { + uint32_t irq_offset; + virtual_addr_t dist_base; + virtual_addr_t cpu_base; +}; + +static struct gic_chip_data gic_data[ARM_GIC_MAX_NR]; + +static inline void arm_gic_write(uint32_t val, virtual_addr_t addr) +{ + arm_writel(val, (void *)(addr)); +} + +static inline uint32_t arm_gic_read(virtual_addr_t addr) +{ + return arm_readl((void *)(addr)); +} + +int arm_gic_active_irq(uint32_t gic_nr) +{ + int ret = -1; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + ret = arm_gic_read(gic_data[gic_nr].cpu_base + + GIC_CPU_INTACK) & 0x3FF; + ret += gic_data[gic_nr].irq_offset; + + return ret; +} + +int arm_gic_ack_irq(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); + arm_gic_write(gic_irq, gic_data[gic_nr].cpu_base + GIC_CPU_EOI); + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_mask(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_CLEAR + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_unmask(uint32_t gic_nr, uint32_t irq) +{ + uint32_t mask = 1 << (irq % 32); + uint32_t gic_irq; + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + if (irq < gic_data[gic_nr].irq_offset) { + return -1; + } + + gic_irq = irq - gic_data[gic_nr].irq_offset; + + arm_gic_write(mask, gic_data[gic_nr].dist_base + + GIC_DIST_ENABLE_SET + (gic_irq / 32) * 4); + + return 0; +} + +int arm_gic_dist_init(uint32_t gic_nr, virtual_addr_t base, uint32_t irq_start) +{ + unsigned int max_irq, i; + uint32_t cpumask = 1 << 0; /*smp_processor_id(); */ + + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + cpumask |= cpumask << 8; + cpumask |= cpumask << 16; + + gic_data[gic_nr].dist_base = base; + gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31; + + arm_gic_write(0, base + GIC_DIST_CTRL); + + /* + * Find out how many interrupts are supported. + */ + max_irq = arm_gic_read(base + GIC_DIST_CTR) & 0x1f; + max_irq = (max_irq + 1) * 32; + + /* + * The GIC only supports up to 1020 interrupt sources. + * Limit this to either the architected maximum, or the + * platform maximum. + */ + if (max_irq > max(1020, ARM_GIC_NR_IRQS)) + max_irq = max(1020, ARM_GIC_NR_IRQS); + + /* + * Set all global interrupts to be level triggered, active low. + */ + for (i = 32; i < max_irq; i += 16) + arm_gic_write(0, base + GIC_DIST_CONFIG + i * 4 / 16); + + /* + * Set all global interrupts to this CPU only. + */ + for (i = 32; i < max_irq; i += 4) + arm_gic_write(cpumask, base + GIC_DIST_TARGET + i * 4 / 4); + + /* + * Set priority on all interrupts. + */ + for (i = 0; i < max_irq; i += 4) + arm_gic_write(0xa0a0a0a0, base + GIC_DIST_PRI + i * 4 / 4); + + /* + * Disable all interrupts. + */ + for (i = 0; i < max_irq; i += 32) + arm_gic_write(0xffffffff, + base + GIC_DIST_ENABLE_CLEAR + i * 4 / 32); + + arm_gic_write(1, base + GIC_DIST_CTRL); + + return 0; +} + +int arm_gic_cpu_init(uint32_t gic_nr, virtual_addr_t base) +{ + if (ARM_GIC_MAX_NR <= gic_nr) { + return -1; + } + + gic_data[gic_nr].cpu_base = base; + + arm_gic_write(0xf0, base + GIC_CPU_PRIMASK); + arm_gic_write(1, base + GIC_CPU_CTRL); + + return 0; +} + +int arm_pic_active_irq(void) +{ + return arm_gic_active_irq(0); +} + +int arm_pic_ack_irq(uint32_t irq) +{ + return arm_gic_ack_irq(0, irq); +} + +int arm_pic_mask(uint32_t irq) +{ + return arm_gic_mask(0, irq); +} + +int arm_pic_unmask(uint32_t irq) +{ + return arm_gic_unmask(0, irq); +} + +int arm_pic_init(void) +{ + int rc = 0; + + rc = arm_gic_dist_init(0, REALVIEW_PBA8_GIC_DIST_BASE, + IRQ_PBA8_GIC_START); + if (rc) { + return rc; + } + rc = arm_gic_cpu_init(0, REALVIEW_PBA8_GIC_CPU_BASE); + if (rc) { + while(1); + } + + return rc; +} + + diff --git a/ports/armv7a/pb-a8/arm_pic.h b/ports/armv7a/pb-a8/arm_pic.h new file mode 100644 index 0000000..d3485f0 --- /dev/null +++ b/ports/armv7a/pb-a8/arm_pic.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_GIC_H__ +#define _ARM_GIC_H__ + +#include +#include + +#define GIC_CPU_CTRL 0x00 +#define GIC_CPU_PRIMASK 0x04 +#define GIC_CPU_BINPOINT 0x08 +#define GIC_CPU_INTACK 0x0c +#define GIC_CPU_EOI 0x10 +#define GIC_CPU_RUNNINGPRI 0x14 +#define GIC_CPU_HIGHPRI 0x18 + +#define GIC_DIST_CTRL 0x000 +#define GIC_DIST_CTR 0x004 +#define GIC_DIST_ENABLE_SET 0x100 +#define GIC_DIST_ENABLE_CLEAR 0x180 +#define GIC_DIST_PENDING_SET 0x200 +#define GIC_DIST_PENDING_CLEAR 0x280 +#define GIC_DIST_ACTIVE_BIT 0x300 +#define GIC_DIST_PRI 0x400 +#define GIC_DIST_TARGET 0x800 +#define GIC_DIST_CONFIG 0xc00 +#define GIC_DIST_SOFTINT 0xf00 + +int arm_pic_active_irq(void); +int arm_pic_ack_irq(uint32_t irq); +int arm_pic_mask(uint32_t irq); +int arm_pic_unmask(uint32_t irq); +int arm_pic_init(void); + +#endif diff --git a/ports/armv7a/pb-a8/arm_plat.h b/ports/armv7a/pb-a8/arm_plat.h new file mode 100644 index 0000000..b226955 --- /dev/null +++ b/ports/armv7a/pb-a8/arm_plat.h @@ -0,0 +1,287 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 _ARM_PLAT_H__ +#define _ARM_PLAT_H__ + +/* + * Memory definitions + */ +#define REALVIEW_BOOT_ROM_LO 0x30000000 /* DoC Base (64Mb)... */ +#define REALVIEW_BOOT_ROM_HI 0x30000000 +#define REALVIEW_BOOT_ROM_BASE REALVIEW_BOOT_ROM_HI /* Normal position */ +#define REALVIEW_BOOT_ROM_SIZE SZ_64M + +#define REALVIEW_SSRAM_BASE /* REALVIEW_SSMC_BASE ? */ +#define REALVIEW_SSRAM_SIZE SZ_2M + +/* + * SDRAM + */ +#define REALVIEW_SDRAM_BASE 0x00000000 + +/* + * Logic expansion modules + * + */ + +/* ------------------------------------------------------------------------ + * RealView Registers + * ------------------------------------------------------------------------ + * + */ +#define REALVIEW_SYS_ID_OFFSET 0x00 +#define REALVIEW_SYS_SW_OFFSET 0x04 +#define REALVIEW_SYS_LED_OFFSET 0x08 +#define REALVIEW_SYS_OSC0_OFFSET 0x0C + +#define REALVIEW_SYS_OSC1_OFFSET 0x10 +#define REALVIEW_SYS_OSC2_OFFSET 0x14 +#define REALVIEW_SYS_OSC3_OFFSET 0x18 +#define REALVIEW_SYS_OSC4_OFFSET 0x1C /* OSC1 for RealView/AB */ + +#define REALVIEW_SYS_LOCK_OFFSET 0x20 +#define REALVIEW_SYS_100HZ_OFFSET 0x24 +#define REALVIEW_SYS_CFGDATA1_OFFSET 0x28 +#define REALVIEW_SYS_CFGDATA2_OFFSET 0x2C +#define REALVIEW_SYS_FLAGS_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSSET_OFFSET 0x30 +#define REALVIEW_SYS_FLAGSCLR_OFFSET 0x34 +#define REALVIEW_SYS_NVFLAGS_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSSET_OFFSET 0x38 +#define REALVIEW_SYS_NVFLAGSCLR_OFFSET 0x3C +#define REALVIEW_SYS_RESETCTL_OFFSET 0x40 +#define REALVIEW_SYS_PCICTL_OFFSET 0x44 +#define REALVIEW_SYS_MCI_OFFSET 0x48 +#define REALVIEW_SYS_FLASH_OFFSET 0x4C +#define REALVIEW_SYS_CLCD_OFFSET 0x50 +#define REALVIEW_SYS_CLCDSER_OFFSET 0x54 +#define REALVIEW_SYS_BOOTCS_OFFSET 0x58 +#define REALVIEW_SYS_24MHz_OFFSET 0x5C +#define REALVIEW_SYS_MISC_OFFSET 0x60 +#define REALVIEW_SYS_IOSEL_OFFSET 0x70 +#define REALVIEW_SYS_PROCID_OFFSET 0x84 +#define REALVIEW_SYS_TEST_OSC0_OFFSET 0xC0 +#define REALVIEW_SYS_TEST_OSC1_OFFSET 0xC4 +#define REALVIEW_SYS_TEST_OSC2_OFFSET 0xC8 +#define REALVIEW_SYS_TEST_OSC3_OFFSET 0xCC +#define REALVIEW_SYS_TEST_OSC4_OFFSET 0xD0 + +#define REALVIEW_SYS_BASE 0x10000000 +#define REALVIEW_SYS_ID (REALVIEW_SYS_BASE + REALVIEW_SYS_ID_OFFSET) +#define REALVIEW_SYS_SW (REALVIEW_SYS_BASE + REALVIEW_SYS_SW_OFFSET) +#define REALVIEW_SYS_LED (REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET) +#define REALVIEW_SYS_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC0_OFFSET) +#define REALVIEW_SYS_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_OSC1_OFFSET) + +#define REALVIEW_SYS_LOCK (REALVIEW_SYS_BASE + REALVIEW_SYS_LOCK_OFFSET) +#define REALVIEW_SYS_100HZ (REALVIEW_SYS_BASE + REALVIEW_SYS_100HZ_OFFSET) +#define REALVIEW_SYS_CFGDATA1 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA1_OFFSET) +#define REALVIEW_SYS_CFGDATA2 (REALVIEW_SYS_BASE + REALVIEW_SYS_CFGDATA2_OFFSET) +#define REALVIEW_SYS_FLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGS_OFFSET) +#define REALVIEW_SYS_FLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSSET_OFFSET) +#define REALVIEW_SYS_FLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_FLAGSCLR_OFFSET) +#define REALVIEW_SYS_NVFLAGS (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGS_OFFSET) +#define REALVIEW_SYS_NVFLAGSSET (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSSET_OFFSET) +#define REALVIEW_SYS_NVFLAGSCLR (REALVIEW_SYS_BASE + REALVIEW_SYS_NVFLAGSCLR_OFFSET) +#define REALVIEW_SYS_RESETCTL (REALVIEW_SYS_BASE + REALVIEW_SYS_RESETCTL_OFFSET) +#define REALVIEW_SYS_PCICTL (REALVIEW_SYS_BASE + REALVIEW_SYS_PCICTL_OFFSET) +#define REALVIEW_SYS_MCI (REALVIEW_SYS_BASE + REALVIEW_SYS_MCI_OFFSET) +#define REALVIEW_SYS_FLASH (REALVIEW_SYS_BASE + REALVIEW_SYS_FLASH_OFFSET) +#define REALVIEW_SYS_CLCD (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCD_OFFSET) +#define REALVIEW_SYS_CLCDSER (REALVIEW_SYS_BASE + REALVIEW_SYS_CLCDSER_OFFSET) +#define REALVIEW_SYS_BOOTCS (REALVIEW_SYS_BASE + REALVIEW_SYS_BOOTCS_OFFSET) +#define REALVIEW_SYS_24MHz (REALVIEW_SYS_BASE + REALVIEW_SYS_24MHz_OFFSET) +#define REALVIEW_SYS_MISC (REALVIEW_SYS_BASE + REALVIEW_SYS_MISC_OFFSET) +#define REALVIEW_SYS_IOSEL (REALVIEW_SYS_BASE + REALVIEW_SYS_IOSEL_OFFSET) +#define REALVIEW_SYS_PROCID (REALVIEW_SYS_BASE + REALVIEW_SYS_PROCID_OFFSET) +#define REALVIEW_SYS_TEST_OSC0 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC0_OFFSET) +#define REALVIEW_SYS_TEST_OSC1 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC1_OFFSET) +#define REALVIEW_SYS_TEST_OSC2 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC2_OFFSET) +#define REALVIEW_SYS_TEST_OSC3 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC3_OFFSET) +#define REALVIEW_SYS_TEST_OSC4 (REALVIEW_SYS_BASE + REALVIEW_SYS_TEST_OSC4_OFFSET) + +/* + * Values for REALVIEW_SYS_RESET_CTRL + */ +#define REALVIEW_SYS_CTRL_RESET_CONFIGCLR 0x01 +#define REALVIEW_SYS_CTRL_RESET_CONFIGINIT 0x02 +#define REALVIEW_SYS_CTRL_RESET_DLLRESET 0x03 +#define REALVIEW_SYS_CTRL_RESET_PLLRESET 0x04 +#define REALVIEW_SYS_CTRL_RESET_POR 0x05 +#define REALVIEW_SYS_CTRL_RESET_DoC 0x06 + +#define REALVIEW_SYS_CTRL_LED (1 << 0) + +/* ------------------------------------------------------------------------ + * RealView control registers + * ------------------------------------------------------------------------ + */ + +/* + * REALVIEW_IDFIELD + * + * 31:24 = manufacturer (0x41 = ARM) + * 23:16 = architecture (0x08 = AHB system bus, ASB processor bus) + * 15:12 = FPGA (0x3 = XVC600 or XVC600E) + * 11:4 = build value + * 3:0 = revision number (0x1 = rev B (AHB)) + */ + +/* + * REALVIEW_SYS_LOCK + * control access to SYS_OSCx, SYS_CFGDATAx, SYS_RESETCTL, + * SYS_CLD, SYS_BOOTCS + */ +#define REALVIEW_SYS_LOCK_LOCKED (1 << 16) +#define REALVIEW_SYS_LOCKVAL_MASK 0xFFFF /* write 0xA05F to enable write access */ + +/* + * REALVIEW_SYS_FLASH + */ +#define REALVIEW_FLASHPROG_FLVPPEN (1 << 0) /* Enable writing to flash */ + +/* + * REALVIEW_INTREG + * - used to acknowledge and control MMCI and UART interrupts + */ +#define REALVIEW_INTREG_WPROT 0x00 /* MMC protection status (no interrupt generated) */ +#define REALVIEW_INTREG_RI0 0x01 /* Ring indicator UART0 is asserted, */ +#define REALVIEW_INTREG_CARDIN 0x08 /* MMCI card in detect */ + /* write 1 to acknowledge and clear */ +#define REALVIEW_INTREG_RI1 0x02 /* Ring indicator UART1 is asserted, */ +#define REALVIEW_INTREG_CARDINSERT 0x03 /* Signal insertion of MMC card */ + +/* + * RealView common peripheral addresses + */ +#define REALVIEW_SCTL_BASE 0x10001000 /* System controller */ +#define REALVIEW_I2C_BASE 0x10002000 /* I2C control */ +#define REALVIEW_AACI_BASE 0x10004000 /* Audio */ +#define REALVIEW_MMCI0_BASE 0x10005000 /* MMC interface */ +#define REALVIEW_KMI0_BASE 0x10006000 /* KMI interface */ +#define REALVIEW_KMI1_BASE 0x10007000 /* KMI 2nd interface */ +#define REALVIEW_CHAR_LCD_BASE 0x10008000 /* Character LCD */ +#define REALVIEW_SCI_BASE 0x1000E000 /* Smart card controller */ +#define REALVIEW_GPIO1_BASE 0x10014000 /* GPIO port 1 */ +#define REALVIEW_GPIO2_BASE 0x10015000 /* GPIO port 2 */ +#define REALVIEW_DMC_BASE 0x10018000 /* DMC configuration */ +#define REALVIEW_DMAC_BASE 0x10030000 /* DMA controller */ + +/* PCI space */ +#define REALVIEW_PCI_BASE 0x41000000 /* PCI Interface */ +#define REALVIEW_PCI_CFG_BASE 0x42000000 +#define REALVIEW_PCI_MEM_BASE0 0x44000000 +#define REALVIEW_PCI_MEM_BASE1 0x50000000 +#define REALVIEW_PCI_MEM_BASE2 0x60000000 +/* Sizes of above maps */ +#define REALVIEW_PCI_BASE_SIZE 0x01000000 +#define REALVIEW_PCI_CFG_BASE_SIZE 0x02000000 +#define REALVIEW_PCI_MEM_BASE0_SIZE 0x0c000000 /* 32Mb */ +#define REALVIEW_PCI_MEM_BASE1_SIZE 0x10000000 /* 256Mb */ +#define REALVIEW_PCI_MEM_BASE2_SIZE 0x10000000 /* 256Mb */ + +#define REALVIEW_SDRAM67_BASE 0x70000000 /* SDRAM banks 6 and 7 */ +#define REALVIEW_LT_BASE 0x80000000 /* Logic Tile expansion */ + +/* + * CompactFlash + */ +#define REALVIEW_CF_BASE 0x18000000 /* CompactFlash */ +#define REALVIEW_CF_MEM_BASE 0x18003000 /* SMC for CompactFlash */ + +/* + * Disk on Chip + */ +#define REALVIEW_DOC_BASE 0x2C000000 +#define REALVIEW_DOC_SIZE (16 << 20) +#define REALVIEW_DOC_PAGE_SIZE 512 +#define REALVIEW_DOC_TOTAL_PAGES (DOC_SIZE / PAGE_SIZE) + +#define ERASE_UNIT_PAGES 32 +#define START_PAGE 0x80 + +/* + * LED settings, bits [7:0] + */ +#define REALVIEW_SYS_LED0 (1 << 0) +#define REALVIEW_SYS_LED1 (1 << 1) +#define REALVIEW_SYS_LED2 (1 << 2) +#define REALVIEW_SYS_LED3 (1 << 3) +#define REALVIEW_SYS_LED4 (1 << 4) +#define REALVIEW_SYS_LED5 (1 << 5) +#define REALVIEW_SYS_LED6 (1 << 6) +#define REALVIEW_SYS_LED7 (1 << 7) + +#define ALL_LEDS 0xFF + +#define LED_BANK REALVIEW_SYS_LED + +/* + * Control registers + */ +#define REALVIEW_IDFIELD_OFFSET 0x0 /* RealView build information */ +#define REALVIEW_FLASHPROG_OFFSET 0x4 /* Flash devices */ +#define REALVIEW_INTREG_OFFSET 0x8 /* Interrupt control */ +#define REALVIEW_DECODE_OFFSET 0xC /* Fitted logic modules */ + +/* + * Clean base - dummy + * + */ +#define CLEAN_BASE REALVIEW_BOOT_ROM_HI + +/* + * System controller bit assignment + */ +#define REALVIEW_REFCLK 0 +#define REALVIEW_TIMCLK 1 + +#define REALVIEW_TIMER1_EnSel 15 +#define REALVIEW_TIMER2_EnSel 17 +#define REALVIEW_TIMER3_EnSel 19 +#define REALVIEW_TIMER4_EnSel 21 + +#define MAX_TIMER 2 +#define MAX_PERIOD 699050 +#define TICKS_PER_uSEC 1 + +/* + * These are useconds NOT ticks. + * + */ +#define mSEC_1 1000 +#define mSEC_5 (mSEC_1 * 5) +#define mSEC_10 (mSEC_1 * 10) +#define mSEC_25 (mSEC_1 * 25) +#define SEC_1 (mSEC_1 * 1000) + +#define REALVIEW_CSR_BASE 0x10000000 +#define REALVIEW_CSR_SIZE 0x10000000 + +#endif diff --git a/ports/armv7a/pb-a8/arm_timer.c b/ports/armv7a/pb-a8/arm_timer.c new file mode 100644 index 0000000..e3f753f --- /dev/null +++ b/ports/armv7a/pb-a8/arm_timer.c @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include +#include +#include +#include +#include +#include + +unsigned long long jiffies; + +void arm_timer_enable(void) +{ + uint32_t ctrl; + + ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + ctrl |= TIMER_CTRL_ENABLE; + arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); +} + +void arm_timer_disable(void) +{ + uint32_t ctrl; + + ctrl = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + ctrl &= ~TIMER_CTRL_ENABLE; + arm_writel(ctrl, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); +} + +void arm_timer_clearirq(void) +{ + arm_writel(1, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_INTCLR)); +} + +int arm_timer_irqhndl(uint32_t irq_no, pt_regs_t * regs) +{ + /* Call the OS system tick handler */ + atomTimerTick(); + + arm_timer_clearirq(); + + return 0; +} + +int arm_timer_init(uint32_t ticks_per_sec) +{ + uint32_t val; + + /* + * set clock frequency: + * REALVIEW_TIMCLK is 1MHz + */ + val = arm_readl((void *)REALVIEW_SCTL_BASE) | (REALVIEW_TIMCLK << 0x1); + arm_writel(val, (void *)REALVIEW_SCTL_BASE); + + /* Register interrupt handler */ + arm_irq_register(IRQ_PBA8_TIMER0_1, &arm_timer_irqhndl); + + val = arm_readl((void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + val &= ~TIMER_CTRL_ENABLE; + val |= (TIMER_CTRL_32BIT | TIMER_CTRL_PERIODIC | TIMER_CTRL_IE); + arm_writel(val, (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_CTRL)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_LOAD)); + arm_writel((1000000 / ticks_per_sec), + (void *)(REALVIEW_PBA8_TIMER0_1_BASE + TIMER_VALUE)); + + return 0; +} diff --git a/ports/armv7a/pb-a8/arm_timer.h b/ports/armv7a/pb-a8/arm_timer.h new file mode 100644 index 0000000..23c921c --- /dev/null +++ b/ports/armv7a/pb-a8/arm_timer.h @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_TIMER_H +#define __ARM_TIMER_H + +#include + +#define TIMER_LOAD 0x00 +#define TIMER_VALUE 0x04 +#define TIMER_CTRL 0x08 +#define TIMER_CTRL_ONESHOT (1 << 0) +#define TIMER_CTRL_32BIT (1 << 1) +#define TIMER_CTRL_DIV1 (0 << 2) +#define TIMER_CTRL_DIV16 (1 << 2) +#define TIMER_CTRL_DIV256 (2 << 2) +#define TIMER_CTRL_IE (1 << 5) /* Interrupt Enable (versatile only) */ +#define TIMER_CTRL_PERIODIC (1 << 6) +#define TIMER_CTRL_ENABLE (1 << 7) + +#define TIMER_INTCLR 0x0c +#define TIMER_RIS 0x10 +#define TIMER_MIS 0x14 +#define TIMER_BGLOAD 0x18 + +void arm_timer_enable(void); +void arm_timer_disable(void); +void arm_timer_clearirq(void); +int arm_timer_init(uint32_t ticks_per_sec); + +#endif /* __ARM_TIMER_H */ diff --git a/ports/armv7a/pb-a8/arm_uart.c b/ports/armv7a/pb-a8/arm_uart.c new file mode 100644 index 0000000..9b423fa --- /dev/null +++ b/ports/armv7a/pb-a8/arm_uart.c @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 +#include + +void arm_uart_putc(uint8_t ch) +{ + unsigned int base = 0x10009000; + if(ch=='\n') { + /* Wait until there is space in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); + + /* Send the character */ + arm_writel('\r', (void*)(base + UART_PL01x_DR)); + } + + /* Wait until there is space in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_TXFF); + + /* Send the character */ + arm_writel(ch, (void*)(base + UART_PL01x_DR)); +} + +uint8_t arm_uart_getc(void) +{ + unsigned int base = 0x10009000; + uint8_t data; + + /* Wait until there is data in the FIFO */ + while (arm_readl((void*)(base + UART_PL01x_FR)) & UART_PL01x_FR_RXFE); + + data = arm_readl((void*)(base + UART_PL01x_DR)); + + /* Check for an error flag */ + if (data & 0xFFFFFF00) { + /* Clear the error */ + arm_writel(0xFFFFFFFF, (void*)(base + UART_PL01x_ECR)); + return -1; + } + + return data; +} + +void arm_uart_init(void) +{ + unsigned int base = 0x10009000; + unsigned int baudrate = 115200; + unsigned int input_clock = 24000000; + unsigned int divider; + unsigned int temp; + unsigned int remainder; + unsigned int fraction; + + /* First, disable everything */ + arm_writel(0x0, (void*)(base + UART_PL011_CR)); + + /* + * Set baud rate + * + * IBRD = UART_CLK / (16 * BAUD_RATE) + * FBRD = RND((64 * MOD(UART_CLK,(16 * BAUD_RATE))) + * / (16 * BAUD_RATE)) + */ + temp = 16 * baudrate; + divider = input_clock / temp; + remainder = input_clock % temp; + temp = (8 * remainder) / baudrate; + fraction = (temp >> 1) + (temp & 1); + + arm_writel(divider, (void*)(base + UART_PL011_IBRD)); + arm_writel(fraction, (void*)(base + UART_PL011_FBRD)); + + /* Set the UART to be 8 bits, 1 stop bit, + * no parity, fifo enabled + */ + arm_writel((UART_PL011_LCRH_WLEN_8 | UART_PL011_LCRH_FEN), + (void*)(base + UART_PL011_LCRH)); + + /* Finally, enable the UART */ + arm_writel((UART_PL011_CR_UARTEN | + UART_PL011_CR_TXE | + UART_PL011_CR_RXE), + (void*)(base + UART_PL011_CR)); +} + diff --git a/ports/armv7a/pb-a8/arm_uart.h b/ports/armv7a/pb-a8/arm_uart.h new file mode 100644 index 0000000..67d47d1 --- /dev/null +++ b/ports/armv7a/pb-a8/arm_uart.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2011, Anup Patel. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ARM_UART_H_ +#define __ARM_UART_H_ + +#include + +/* + * ARM PrimeCell UART's (PL010 & PL011) + * ------------------------------------ + * + * Definitions common to both PL010 & PL011 + * + */ +#define UART_PL01x_DR 0x00 /* Data read or written from the interface. */ +#define UART_PL01x_RSR 0x04 /* Receive status register (Read). */ +#define UART_PL01x_ECR 0x04 /* Error clear register (Write). */ +#define UART_PL01x_FR 0x18 /* Flag register (Read only). */ + +#define UART_PL01x_RSR_OE 0x08 +#define UART_PL01x_RSR_BE 0x04 +#define UART_PL01x_RSR_PE 0x02 +#define UART_PL01x_RSR_FE 0x01 + +#define UART_PL01x_FR_TXFE 0x80 +#define UART_PL01x_FR_RXFF 0x40 +#define UART_PL01x_FR_TXFF 0x20 +#define UART_PL01x_FR_RXFE 0x10 +#define UART_PL01x_FR_BUSY 0x08 +#define UART_PL01x_FR_TMSK (UART_PL01x_FR_TXFF + UART_PL01x_FR_BUSY) + +/* + * PL011 definitions + * + */ +#define UART_PL011_IBRD 0x24 +#define UART_PL011_FBRD 0x28 +#define UART_PL011_LCRH 0x2C +#define UART_PL011_CR 0x30 +#define UART_PL011_IMSC 0x38 +#define UART_PL011_PERIPH_ID0 0xFE0 + +#define UART_PL011_LCRH_SPS (1 << 7) +#define UART_PL011_LCRH_WLEN_8 (3 << 5) +#define UART_PL011_LCRH_WLEN_7 (2 << 5) +#define UART_PL011_LCRH_WLEN_6 (1 << 5) +#define UART_PL011_LCRH_WLEN_5 (0 << 5) +#define UART_PL011_LCRH_FEN (1 << 4) +#define UART_PL011_LCRH_STP2 (1 << 3) +#define UART_PL011_LCRH_EPS (1 << 2) +#define UART_PL011_LCRH_PEN (1 << 1) +#define UART_PL011_LCRH_BRK (1 << 0) + +#define UART_PL011_CR_CTSEN (1 << 15) +#define UART_PL011_CR_RTSEN (1 << 14) +#define UART_PL011_CR_OUT2 (1 << 13) +#define UART_PL011_CR_OUT1 (1 << 12) +#define UART_PL011_CR_RTS (1 << 11) +#define UART_PL011_CR_DTR (1 << 10) +#define UART_PL011_CR_RXE (1 << 9) +#define UART_PL011_CR_TXE (1 << 8) +#define UART_PL011_CR_LPE (1 << 7) +#define UART_PL011_CR_IIRLP (1 << 2) +#define UART_PL011_CR_SIREN (1 << 1) +#define UART_PL011_CR_UARTEN (1 << 0) + +#define UART_PL011_IMSC_OEIM (1 << 10) +#define UART_PL011_IMSC_BEIM (1 << 9) +#define UART_PL011_IMSC_PEIM (1 << 8) +#define UART_PL011_IMSC_FEIM (1 << 7) +#define UART_PL011_IMSC_RTIM (1 << 6) +#define UART_PL011_IMSC_TXIM (1 << 5) +#define UART_PL011_IMSC_RXIM (1 << 4) +#define UART_PL011_IMSC_DSRMIM (1 << 3) +#define UART_PL011_IMSC_DCDMIM (1 << 2) +#define UART_PL011_IMSC_CTSMIM (1 << 1) +#define UART_PL011_IMSC_RIMIM (1 << 0) + +uint8_t arm_uart_getc(void); +void arm_uart_putc(uint8_t ch); +void arm_uart_init(void); + +#endif /* __ARM_UART_H_ */ diff --git a/ports/armv7a/printk.c b/ports/armv7a/printk.c new file mode 100644 index 0000000..99d137f --- /dev/null +++ b/ports/armv7a/printk.c @@ -0,0 +1,59 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include +#include +#include + +static int8_t buf[2048]; + +/* Uses the above routine to output a string... */ +void puts(const uint8_t *text) +{ + int32_t i; + + for (i = 0; i < strlen((const int8_t *)text); i++) { + arm_uart_putc(text[i]); + } +} + +void printk(const char *format, ...) +{ + va_list args; + int i; + + va_start(args, format); + i = vsprintf(buf, (const int8_t *)format, args); + va_end(args); + + puts((const uint8_t *)buf); +} + diff --git a/ports/armv7a/printk.h b/ports/armv7a/printk.h new file mode 100644 index 0000000..bd1b192 --- /dev/null +++ b/ports/armv7a/printk.h @@ -0,0 +1,42 @@ +/* + * This file is part of Freax kernel. + * + * Copyright (c) Himanshu Chauhan 2009-10. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _PRINTK_H +#define _PRINTK_H + +#include "atomport.h" + +extern void putch (uint8_t ch); +extern void puts (const uint8_t *text); +extern void printk (const char*format, ...); + +#endif diff --git a/ports/armv7a/stdarg.h b/ports/armv7a/stdarg.h new file mode 100755 index 0000000..fd79ec0 --- /dev/null +++ b/ports/armv7a/stdarg.h @@ -0,0 +1,28 @@ +#ifndef _STDARG_H +#define _STDARG_H + +typedef char *va_list; + +/* Amount of space required in an argument list for an arg of type TYPE. + TYPE may alternatively be an expression whose type is used. */ + +#define __va_rounded_size(TYPE) \ + (((sizeof (TYPE) + sizeof (int) - 1) / sizeof (int)) * sizeof (int)) + +#ifndef __sparc__ +#define va_start(AP, LASTARG) \ + (AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#else +#define va_start(AP, LASTARG) \ + (__builtin_saveregs (), \ + AP = ((char *) &(LASTARG) + __va_rounded_size (LASTARG))) +#endif + +void va_end (va_list); /* Defined in gnulib */ +#define va_end(AP) + +#define va_arg(AP, TYPE) \ + (AP += __va_rounded_size (TYPE), \ + *((TYPE *) (AP - __va_rounded_size (TYPE)))) + +#endif /* _STDARG_H */ diff --git a/ports/armv7a/string.c b/ports/armv7a/string.c new file mode 100644 index 0000000..b99b529 --- /dev/null +++ b/ports/armv7a/string.c @@ -0,0 +1,61 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 +#include + +void *memcpy(void *dest, const void *src, size_t count) +{ + const int8_t *sp = (const int8_t *)src; + int8_t *dp = (int8_t *)dest; + for(; count != 0; count--) *dp++ = *sp++; + return dest; +} + +void *memset(void *dest, int8_t val, size_t count) +{ + int8_t *temp = (int8_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count) +{ + uint16_t *temp = (uint16_t *)dest; + for( ; count != 0; count--) *temp++ = val; + return dest; +} + +size_t strlen(const int8_t *str) +{ + size_t retval; + for(retval = 0; *str != '\0'; str++) retval++; + return retval; +} diff --git a/ports/armv7a/string.h b/ports/armv7a/string.h new file mode 100644 index 0000000..bbccc25 --- /dev/null +++ b/ports/armv7a/string.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 __STRING_H +#define __STRING_H + +#include + +void *memcpy(void *dest, const void *src, size_t count); +void *memset(void *dest, int8_t val, size_t count); +uint16_t *memsetw(uint16_t *dest, uint16_t val, size_t count); +size_t strlen(const int8_t *str); + +#endif /* __STRING_H */ + diff --git a/ports/armv7a/system.h b/ports/armv7a/system.h new file mode 100644 index 0000000..b8c25ad --- /dev/null +++ b/ports/armv7a/system.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) Himanshu Chauhan 2009-11. + * 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. Neither the name of Himanshu Chauhan 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 COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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 _SYSTEM_H +#define _SYSTEM_H + +#include +#include + +extern const uint8_t *kernel_name; +extern const uint8_t *kernel_version; +extern const uint8_t *kernel_bdate; +extern const uint8_t *kernel_btime; + +extern void *memcpy (void *dest, const void *src, size_t count); +extern void *memset (void *dest, int8_t val, size_t count); +extern uint16_t *memsetw (uint16_t *dest, uint16_t val, size_t count); +extern size_t strlen (const int8_t *str); +extern int vsprintf (int8_t *buf, const int8_t *fmt, va_list args); +extern void init_console (void); +extern int32_t arch_init (void); +extern uint8_t ioreadb (void *addr); +extern void iowriteb (void *addr, uint8_t data); + +#endif /* _SYSTEM_H */ diff --git a/ports/armv7a/vsprintf.c b/ports/armv7a/vsprintf.c new file mode 100644 index 0000000..c8819fd --- /dev/null +++ b/ports/armv7a/vsprintf.c @@ -0,0 +1,244 @@ +/* vsprintf.c -- Lars Wirzenius & Linus Torvalds. */ +/* + * Wirzenius wrote this portably, Torvalds fucked it up :-) + * and Himanshu Fucked it up further :)) + */ + +#include +#include +#include + +/* we use this so that we can do without the ctype library */ +#define is_digit(c) ((c) >= '0' && (c) <= '9') + +static int skip_atoi(const int8_t **s) +{ + int i=0; + + while (is_digit(**s)) + i = i*10 + *((*s)++) - '0'; + return i; +} + +#define ZEROPAD 1 /* pad with zero */ +#define SIGN 2 /* unsigned/signed long */ +#define PLUS 4 /* show plus */ +#define SPACE 8 /* space if plus */ +#define LEFT 16 /* left justified */ +#define SPECIAL 32 /* 0x */ +#define SMALL 64 /* use 'abcdef' instead of 'ABCDEF' */ + +/*#define do_div(n,base) ({ \ +int __res; \ +__asm__("divl %4":"=a" (n),"=d" (__res):"0" (n),"1" (0),"r" (base)); \ +__res; })*/ + +static uint32_t do_div (int32_t *n, int32_t base) +{ + uint32_t remainder = *n % base; + *n /= base; + return remainder; +} + +static int8_t * number(int8_t * str, int num, int32_t base, + int32_t size, int32_t precision, int32_t type) +{ + int8_t c,sign,tmp[36]; + const int8_t *digits=(const int8_t *)"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + int32_t i; + + if (type & SMALL) digits = (const int8_t *)"0123456789abcdefghijklmnopqrstuvwxyz"; + if (type & LEFT) type &= ~ZEROPAD; + if (base < 2 || base > 36) + return 0; + c = (type & ZEROPAD) ? '0' : ' ' ; + if (type & SIGN && num < 0) { + sign = '-'; + num = -num; + } else + sign = (type & PLUS) ? '+' : ((type & SPACE) ? ' ' : 0); + if (sign) size--; + + if (type & SPECIAL) { + if (base == 16) { + size -= 2; + } else if (base == 8) { + size--; + } + } + + i = 0; + if (num == 0) + tmp[i++] = '0'; + else while (num != 0) + tmp[i++] = digits[do_div(&num,base)]; + if (i > precision) precision = i; + size -= precision; + if (!(type & (ZEROPAD + LEFT))) + while(size-- > 0) + *str++ = ' '; + if (sign) + *str++ = sign; + if (type & SPECIAL) { + if (base == 8) { + *str++ = '0'; + } else if (base == 16) { + *str++ = '0'; + *str++ = digits[33]; + } + } + + if (!(type & LEFT)) + while(size-- > 0) + *str++ = c; + while(i < precision--) + *str++ = '0'; + while(i-- > 0) + *str++ = tmp[i]; + while(size-- > 0) + *str++ = ' '; + return str; +} + +int32_t vsprintf (int8_t *buf, const int8_t *fmt, va_list args) +{ + int32_t len; + int32_t i; + int8_t * str; + int8_t *s; + int32_t *ip; + + int32_t flags; /* flags to number() */ + + int32_t field_width; /* width of output field */ + int32_t precision; /* min. # of digits for integers; max + number of chars for from string */ + int32_t qualifier; /* 'h', 'l', or 'L' for integer fields */ + + for (str=buf ; *fmt ; ++fmt) { + if (*fmt != '%') { + *str++ = *fmt; + continue; + } + + /* process flags */ + flags = 0; + repeat: + ++fmt; /* this also skips first '%' */ + switch (*fmt) { + case '-': flags |= LEFT; goto repeat; + case '+': flags |= PLUS; goto repeat; + case ' ': flags |= SPACE; goto repeat; + case '#': flags |= SPECIAL; goto repeat; + case '0': flags |= ZEROPAD; goto repeat; + } + + /* get field width */ + field_width = -1; + if (is_digit(*fmt)) + field_width = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + field_width = va_arg(args, int); + if (field_width < 0) { + field_width = -field_width; + flags |= LEFT; + } + } + + /* get the precision */ + precision = -1; + if (*fmt == '.') { + ++fmt; + if (is_digit(*fmt)) + precision = skip_atoi(&fmt); + else if (*fmt == '*') { + /* it's the next argument */ + precision = va_arg(args, int); + } + if (precision < 0) + precision = 0; + } + + /* get the conversion qualifier */ + qualifier = -1; + if (*fmt == 'h' || *fmt == 'l' || *fmt == 'L') { + qualifier = *fmt; + ++fmt; + } + + switch (*fmt) { + case 'c': + if (!(flags & LEFT)) + while (--field_width > 0) + *str++ = ' '; + *str++ = (unsigned char) va_arg(args, int); + while (--field_width > 0) + *str++ = ' '; + break; + + case 's': + s = va_arg(args, int8_t *); + len = strlen(s); + if (precision < 0) + precision = len; + else if (len > precision) + len = precision; + + if (!(flags & LEFT)) + while (len < field_width--) + *str++ = ' '; + for (i = 0; i < len; ++i) + *str++ = *s++; + while (len < field_width--) + *str++ = ' '; + break; + + case 'o': + str = number(str, va_arg(args, unsigned long), 8, + field_width, precision, flags); + break; + + case 'p': + if (field_width == -1) { + field_width = 8; + flags |= ZEROPAD; + } + str = number(str, + (unsigned long) va_arg(args, void *), 16, + field_width, precision, flags); + break; + + case 'x': + flags |= SMALL; + case 'X': + str = number(str, va_arg(args, unsigned long), 16, + field_width, precision, flags); + break; + + case 'd': + case 'i': + flags |= SIGN; + case 'u': + str = number(str, va_arg(args, unsigned long), 10, + field_width, precision, flags); + break; + + case 'n': + ip = va_arg(args, int32_t *); + *ip = (str - buf); + break; + + default: + if (*fmt != '%') + *str++ = '%'; + if (*fmt) + *str++ = *fmt; + else + --fmt; + break; + } + } + *str = '\0'; + return str-buf; +} From 112928594ce3065c428d081e9b0297e5b8c55f2b Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Sat, 9 Jul 2011 10:43:27 +0530 Subject: [PATCH 55/76] Updated archLongJump make is more stable. All test cases from testsuite work properly. --- ports/armv7a/atomport-asm.S | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/ports/armv7a/atomport-asm.S b/ports/armv7a/atomport-asm.S index 9208fc4..6dd6160 100644 --- a/ports/armv7a/atomport-asm.S +++ b/ports/armv7a/atomport-asm.S @@ -59,19 +59,15 @@ archSetJump: .globl archLongJump archLongJump: mrs r1, cpsr_all - SET_CURRENT_MODE CPSR_MODE_UNDEFINED - mov sp, r0 - SET_CURRENT_MODE CPSR_MODE_ABORT - mov sp, r0 SET_CURRENT_MODE CPSR_MODE_IRQ mov sp, r0 SET_CURRENT_MODE CPSR_MODE_FIQ mov sp, r0 msr cpsr_all, r1 ldr r1, [r0], #4 /* Get CPSR from stack */ + orr r2, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) + msr cpsr_all, r2 msr spsr_all, r1 - orr r1, r1, #(CPSR_IRQ_DISABLED | CPSR_FIQ_DISABLED) - msr cpsr_all, r1 ldm r0, {r0-r15}^ mov r0, r0 /* NOP */ From 2e075ad4138324f0df28e51a52e5553a91ebd189 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 13 Jul 2011 16:30:04 +0530 Subject: [PATCH 56/76] Added .bin file generation for .elf files for convinence in Makefile. Signed-off-by: Anup Patel --- ports/armv7a/Makefile | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/ports/armv7a/Makefile b/ports/armv7a/Makefile index a066851..edf7242 100644 --- a/ports/armv7a/Makefile +++ b/ports/armv7a/Makefile @@ -74,8 +74,10 @@ build_objs = $(foreach obj,$(objs),$(build_dir)/$(obj)) # Target application filenames .elf for each test object tobjs = $(notdir $(patsubst %.c,%.o,$(wildcard $(tests_dir)/*.c))) telfs = $(patsubst %.o,%.elf,$(tobjs)) +tbins = $(patsubst %.o,%.bin,$(tobjs)) build_tobjs = $(foreach tobj,$(tobjs),$(build_dir)/$(tobj)) build_telfs = $(foreach telf,$(telfs),$(build_dir)/$(telf)) +build_tbins = $(foreach tbin,$(tbins),$(build_dir)/$(tbin)) # GCC flags CFLAGS= -g \ @@ -98,7 +100,12 @@ endif # All .PHONY: all -all: $(build_telfs) $(build_tobjs) $(build_objs) Makefile +all: $(build_tbins) $(build_telfs) $(build_tobjs) $(build_objs) Makefile + +$(build_dir)/%.bin: $(build_dir)/%.elf + $(V)mkdir -p `dirname $@` + $(if $(V), @echo " (OBJCOPY) $(subst $(build_dir)/,,$@)") + $(V)$(OBJCOPY) -O binary $< $@ $(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) $(V)mkdir -p `dirname $@` From a96a1afbc7659e051d41289e9d056359e1f98197 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 21:54:29 +0100 Subject: [PATCH 57/76] Remove AVR-specific comments from MIPS Makefile. --- ports/mips/Makefile | 3 --- 1 file changed, 3 deletions(-) diff --git a/ports/mips/Makefile b/ports/mips/Makefile index 04d340b..2254250 100644 --- a/ports/mips/Makefile +++ b/ports/mips/Makefile @@ -4,9 +4,6 @@ # Build all test applications: # make -# -# Program a test application using UISP (appname => test app e.g. sems1): -# make program app=appname # Location of build tools and atomthreads sources KERNEL_DIR=../../kernel From d64a52452225dbe17198414a2e9ad52f6fc56da0 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 21:56:07 +0100 Subject: [PATCH 58/76] Add qemu/ddd instructions to MIPS readme. --- ports/mips/README | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ports/mips/README b/ports/mips/README index 5f778c8..d0ca2af 100644 --- a/ports/mips/README +++ b/ports/mips/README @@ -1,3 +1,8 @@ * Required Ubuntu packages: qemu, qemu-kvm-extras + * Lucid 0.12.3 no good, better to install from source, make && sudo make install * Compiler: CodeSourcery * Run test: qemu-system-mips -M mips -m 128 -kernel build/kern1.elf -nographic + + * GDB: Add -S -s to qemu startup + * mips-linux-gnu-gdb, target remote localhost:1234, file build/mutex5.elf + * ddd ---debugger mips-linux-gnu-gdb build/mutex5.elf From 0ec7a4629edd2537dacdb7f03d4203306a82ffd1 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 22:50:11 +0100 Subject: [PATCH 59/76] Change avr folders to armv7a. --- ports/armv7a/Doxyfile | 2 +- ports/armv7a/Makefile | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/ports/armv7a/Doxyfile b/ports/armv7a/Doxyfile index e6f6571..d89146a 100644 --- a/ports/armv7a/Doxyfile +++ b/ports/armv7a/Doxyfile @@ -30,7 +30,7 @@ PROJECT_NUMBER = # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. -OUTPUT_DIRECTORY = doxygen-avr +OUTPUT_DIRECTORY = doxygen-armv7a # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output diff --git a/ports/armv7a/Makefile b/ports/armv7a/Makefile index edf7242..6c0ec7f 100644 --- a/ports/armv7a/Makefile +++ b/ports/armv7a/Makefile @@ -136,7 +136,7 @@ $(build_dir)/%.o: $(tests_dir)/%.c .PHONY: clean clean: rm -rf doxygen-kernel - rm -rf doxygen-avr + rm -rf doxygen-armv7a rm -rf $(build_dir) # Docs .PHONY: doxygen From 1ca423d8f6a856522efa838212eaee88d879378a Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 22:51:54 +0100 Subject: [PATCH 60/76] Minor changes for consistency with other ports. --- ports/armv7a/atomport-tests.h | 4 ++- ports/armv7a/atomport.h | 54 +++++++++++++++++++++-------------- ports/armv7a/printk.c | 7 +++-- ports/armv7a/vsprintf.c | 4 +-- 4 files changed, 41 insertions(+), 28 deletions(-) diff --git a/ports/armv7a/atomport-tests.h b/ports/armv7a/atomport-tests.h index d76e27d..cf3465a 100644 --- a/ports/armv7a/atomport-tests.h +++ b/ports/armv7a/atomport-tests.h @@ -33,8 +33,10 @@ /* Include Atomthreads kernel API */ #include "atom.h" +/* Prerequisite include for ATOMLOG() macro (via printf) */ +#include "printk.h" + /* Logger macro for viewing test results */ -/* FIXME: Add uart out routine once uart is supported */ #define ATOMLOG printk #define _STR diff --git a/ports/armv7a/atomport.h b/ports/armv7a/atomport.h index 487df12..87a7bca 100644 --- a/ports/armv7a/atomport.h +++ b/ports/armv7a/atomport.h @@ -31,17 +31,33 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H + /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 1000 -typedef signed int int32_t; -typedef signed short int16_t; -typedef signed char int8_t; -typedef unsigned int uint32_t; -typedef unsigned short uint16_t; -typedef unsigned char uint8_t; -typedef long long int64_t; -typedef unsigned long size_t; +/** + * Definition of NULL. stddef.h not available on this platform. + */ +#define NULL ((void *)(0)) + +/* Size of each stack entry / stack alignment size (32 bits on ARMv7A) */ +#define STACK_ALIGN_SIZE sizeof(uint32_t) + +/** + * Architecture-specific types. + * Provide stdint.h style types. + */ +#define uint8_t unsigned char +#define uint16_t unsigned short +#define uint32_t unsigned int +#define uint64_t unsigned long long +#define int8_t signed char +#define int16_t signed short +#define int32_t signed int +#define int64_t long long +#define size_t unsigned long +#define POINTER void * +#define UINT32 uint32_t typedef unsigned int irq_flags_t; typedef unsigned int virtual_addr_t; @@ -51,17 +67,6 @@ typedef unsigned int physical_size_t; typedef unsigned int clock_freq_t; typedef unsigned long long jiffies_t; -#define UINT32 uint32_t -#define STACK_ALIGN_SIZE sizeof(uint32_t) -#define NULL ((void *)(0)) - -/** - * Architecture-specific types. - * Most of these are available from stdint.h on this platform, which is - * included above. - */ -#define POINTER void * - struct pt_regs { uint32_t cpsr; // Current Program Status uint32_t gpr[13]; // R0 - R12 @@ -71,10 +76,14 @@ struct pt_regs { } __attribute ((packed)) ; typedef struct pt_regs pt_regs_t; -#include -#include -/* Critical region protection */ +/** + * Critical region protection: this should disable interrupts + * to protect OS data structures during modification. It must + * allow nested calls, which means that interrupts should only + * be re-enabled when the outer CRITICAL_END() is reached. + */ +#include "arm_irq.h" #define CRITICAL_STORE irq_flags_t status_flags #define CRITICAL_START() status_flags = arm_irq_save(); #define CRITICAL_END() arm_irq_restore(status_flags); @@ -82,4 +91,5 @@ typedef struct pt_regs pt_regs_t; /* Uncomment to enable stack-checking */ /* #define ATOM_STACK_CHECKING */ + #endif /* __ATOM_PORT_H */ diff --git a/ports/armv7a/printk.c b/ports/armv7a/printk.c index 99d137f..ea52ef3 100644 --- a/ports/armv7a/printk.c +++ b/ports/armv7a/printk.c @@ -28,10 +28,11 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include -#include #include -#include +#include "system.h" +#include "atomport.h" +#include "printk.h" +#include "arm_uart.h" static int8_t buf[2048]; diff --git a/ports/armv7a/vsprintf.c b/ports/armv7a/vsprintf.c index c8819fd..0a89344 100644 --- a/ports/armv7a/vsprintf.c +++ b/ports/armv7a/vsprintf.c @@ -5,8 +5,8 @@ */ #include -#include -#include +#include "system.h" +#include "atomport.h" /* we use this so that we can do without the ctype library */ #define is_digit(c) ((c) >= '0' && (c) <= '9') From fc53574c1275bb99f3d8e20f0df7e4ec3b0531ca Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 22:53:30 +0100 Subject: [PATCH 61/76] Remove TODO, functionality completed. --- ports/mips/atomport-tests.h | 1 - 1 file changed, 1 deletion(-) diff --git a/ports/mips/atomport-tests.h b/ports/mips/atomport-tests.h index 4b44513..0c73b36 100644 --- a/ports/mips/atomport-tests.h +++ b/ports/mips/atomport-tests.h @@ -37,7 +37,6 @@ #include "printk.h" /* Logger macro for viewing test results */ -/* FIXME: Add uart out routine once uart is supported */ #define ATOMLOG printk #define _STR From f9a16861b92bc2f1150ef3968c898fedefa6ea80 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Tue, 19 Jul 2011 23:19:21 +0100 Subject: [PATCH 62/76] Cosmetic changes for consistency with other architecture ports. --- ports/armv7a/arm_irq.h | 5 +-- ports/armv7a/arm_main.c | 52 ++++++++++++++++--------------- ports/armv7a/atomport-private.h | 54 +++++++++++++++++++++++++++++++++ ports/armv7a/atomport.c | 11 +++---- ports/armv7a/atomport.h | 19 +----------- 5 files changed, 90 insertions(+), 51 deletions(-) create mode 100644 ports/armv7a/atomport-private.h diff --git a/ports/armv7a/arm_irq.h b/ports/armv7a/arm_irq.h index 3defb6d..1c6dafb 100644 --- a/ports/armv7a/arm_irq.h +++ b/ports/armv7a/arm_irq.h @@ -30,8 +30,9 @@ #ifndef __ARM_IRQ_H #define __ARM_IRQ_H -#include -#include +#include "atomport.h" +#include "atomport-private.h" +#include "arm_defines.h" typedef int (*arm_irq_handler_t) (uint32_t irq_no, pt_regs_t * regs); diff --git a/ports/armv7a/arm_main.c b/ports/armv7a/arm_main.c index 5546e7d..5384233 100644 --- a/ports/armv7a/arm_main.c +++ b/ports/armv7a/arm_main.c @@ -27,14 +27,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include +#include "atom.h" +#include "atomport.h" +#include "atomtests.h" +#include "atomtimer.h" #include "system.h" -#include -#include -#include +#include "arm_irq.h" +#include "arm_timer.h" +#include "arm_uart.h" /* Constants */ @@ -169,11 +169,11 @@ int main ( void ) IDLE_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { - arm_irq_init(); + arm_irq_init(); - arm_timer_init(SYSTEM_TICKS_PER_SEC); + arm_timer_init(SYSTEM_TICKS_PER_SEC); - arm_uart_init(); + arm_uart_init(); /* Create an application thread */ status = atomThreadCreate(&main_tcb, @@ -182,23 +182,24 @@ int main ( void ) MAIN_STACK_SIZE_BYTES, 0); if (status == ATOM_OK) { - arm_timer_enable(); + arm_timer_enable(); - /** - * First application thread successfully created. It is - * now possible to start the OS. Execution will not return - * from atomOSStart(), which will restore the context of - * our application thread and start executing it. - * - * Note that interrupts are still disabled at this point. - * They will be enabled as we restore and execute our first - * thread in archFirstThreadRestore(). - */ - atomOSStart(); - } + /** + * First application thread successfully created. It is + * now possible to start the OS. Execution will not return + * from atomOSStart(), which will restore the context of + * our application thread and start executing it. + * + * Note that interrupts are still disabled at this point. + * They will be enabled as we restore and execute our first + * thread in archFirstThreadRestore(). + */ + atomOSStart(); + } } - while (1); + while (1) + ; /* There was an error starting the OS if we reach here */ return (0); @@ -227,5 +228,6 @@ static void main_thread_func (uint32_t data) } printk("Reset your board !!!!!"); /* Test finished so just hang !!! */ - while (1); + while (1) + ; } diff --git a/ports/armv7a/atomport-private.h b/ports/armv7a/atomport-private.h new file mode 100644 index 0000000..695777c --- /dev/null +++ b/ports/armv7a/atomport-private.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2011, Atomthreads Project. 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. No personal names or organizations' names associated with the + * Atomthreads project may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ATOMTHREADS PROJECT 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 PROJECT 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 __ATOMPORT_PRIVATE_H_ +#define __ATOMPORT_PRIVATE_H_ + +typedef unsigned int irq_flags_t; +typedef unsigned int virtual_addr_t; +typedef unsigned int virtual_size_t; +typedef unsigned int physical_addr_t; +typedef unsigned int physical_size_t; +typedef unsigned int clock_freq_t; +typedef unsigned long long jiffies_t; + +struct pt_regs { + uint32_t cpsr; // Current Program Status + uint32_t gpr[13]; // R0 - R12 + uint32_t sp; + uint32_t lr; + uint32_t pc; +} __attribute ((packed)) ; +typedef struct pt_regs pt_regs_t; + +/* Function prototypes */ +extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); +extern void archLongJump(pt_regs_t *regs); + +#endif /* __ATOMPORT_PRIVATE_H_ */ diff --git a/ports/armv7a/atomport.c b/ports/armv7a/atomport.c index de52b49..8045a69 100644 --- a/ports/armv7a/atomport.c +++ b/ports/armv7a/atomport.c @@ -28,10 +28,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include +#include "atom.h" +#include "atomport.h" +#include "atomport-private.h" +#include "string.h" +#include "arm_defines.h" /** * This function initialises each thread's stack during creation, before the @@ -68,8 +69,6 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, regs->pc = (uint32_t)entry_point; } -extern int archSetJump(pt_regs_t *regs, uint32_t *tmp); -extern void archLongJump(pt_regs_t *regs); /** * archFirstThreadRestore(ATOM_TCB *new_tcb) diff --git a/ports/armv7a/atomport.h b/ports/armv7a/atomport.h index 87a7bca..0730e21 100644 --- a/ports/armv7a/atomport.h +++ b/ports/armv7a/atomport.h @@ -59,24 +59,6 @@ #define POINTER void * #define UINT32 uint32_t -typedef unsigned int irq_flags_t; -typedef unsigned int virtual_addr_t; -typedef unsigned int virtual_size_t; -typedef unsigned int physical_addr_t; -typedef unsigned int physical_size_t; -typedef unsigned int clock_freq_t; -typedef unsigned long long jiffies_t; - -struct pt_regs { - uint32_t cpsr; // Current Program Status - uint32_t gpr[13]; // R0 - R12 - uint32_t sp; - uint32_t lr; - uint32_t pc; -} __attribute ((packed)) ; -typedef struct pt_regs pt_regs_t; - - /** * Critical region protection: this should disable interrupts * to protect OS data structures during modification. It must @@ -84,6 +66,7 @@ typedef struct pt_regs pt_regs_t; * be re-enabled when the outer CRITICAL_END() is reached. */ #include "arm_irq.h" +#include "atomport-private.h" #define CRITICAL_STORE irq_flags_t status_flags #define CRITICAL_START() status_flags = arm_irq_save(); #define CRITICAL_END() arm_irq_restore(status_flags); From 19536e1fc7efaa80e92a1be85c1e2b866a8597c5 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Wed, 20 Jul 2011 09:28:05 +0530 Subject: [PATCH 63/76] Merge branch 'master', remote branch 'upstream/master' From 48fe6bc12aff3dc9381659458304c2f84f3149d4 Mon Sep 17 00:00:00 2001 From: Himanshu Chauhan Date: Fri, 22 Jul 2011 23:36:17 +0530 Subject: [PATCH 64/76] Fixed Context switch and timer-delay problem with MIPS. Signed-off-by: Himanshu Chauhan --- ports/mips/atomport-asm-macros.h | 123 +++++++++++++------------ ports/mips/atomport-asm.s | 151 +++++++++---------------------- ports/mips/atomport-entry.s | 26 +----- ports/mips/atomport-timer.c | 9 +- ports/mips/atomport.c | 8 +- ports/mips/atomport.h | 15 +-- ports/mips/regs.h | 4 + 7 files changed, 127 insertions(+), 209 deletions(-) diff --git a/ports/mips/atomport-asm-macros.h b/ports/mips/atomport-asm-macros.h index 39b9bb6..137285a 100644 --- a/ports/mips/atomport-asm-macros.h +++ b/ports/mips/atomport-asm-macros.h @@ -47,7 +47,7 @@ fn: nop; \ nop; -#define enable_global_interrupts ei $0 +#define enable_global_interrupts ei #define disable_global_interrupts di $0 #define EXCEPTION_VECTOR(_name, _offset, _where)\ @@ -63,70 +63,69 @@ _name: \ #define LOAD_REG(reg, treg) \ lw reg, ((reg ## _IDX) * 4)(treg) -#define SAVE_INT_CONTEXT \ - addiu sp, sp, -((NUM_REGISTERS + 1)* 4); \ +#define SAVE_INT_CONTEXT(treg) \ mfc0 k1, CP0_EPC; \ - SAVE_REG(t0,sp); \ - SAVE_REG(t1,sp); \ - SAVE_REG(t2,sp); \ - SAVE_REG(t3,sp); \ - SAVE_REG(t4,sp); \ - SAVE_REG(t5,sp); \ - SAVE_REG(t6,sp); \ - SAVE_REG(t7,sp); \ - SAVE_REG(t8,sp); \ - SAVE_REG(t9,sp); \ - SAVE_REG(v0,sp); \ - SAVE_REG(v1,sp); \ - SAVE_REG(a0,sp); \ - SAVE_REG(a1,sp); \ - SAVE_REG(a2,sp); \ - SAVE_REG(a3,sp); \ - SAVE_REG(s0,sp); \ - SAVE_REG(s1,sp); \ - SAVE_REG(s2,sp); \ - SAVE_REG(s3,sp); \ - SAVE_REG(s4,sp); \ - SAVE_REG(s5,sp); \ - SAVE_REG(s6,sp); \ - SAVE_REG(s7,sp); \ - SAVE_REG(gp,sp); \ - SAVE_REG(s8,sp); \ - SAVE_REG(ra,sp); \ - sw k0, (sp_IDX * 4)(sp); \ - sw k1, (NUM_REGISTERS * 4)(sp); + SAVE_REG(t0,treg); \ + SAVE_REG(t1,treg); \ + SAVE_REG(t2,treg); \ + SAVE_REG(t3,treg); \ + SAVE_REG(t4,treg); \ + SAVE_REG(t5,treg); \ + SAVE_REG(t6,treg); \ + SAVE_REG(t7,treg); \ + SAVE_REG(t8,treg); \ + SAVE_REG(t9,treg); \ + SAVE_REG(v0,treg); \ + SAVE_REG(v1,treg); \ + SAVE_REG(a0,treg); \ + SAVE_REG(a1,treg); \ + SAVE_REG(a2,treg); \ + SAVE_REG(a3,treg); \ + SAVE_REG(s0,treg); \ + SAVE_REG(s1,treg); \ + SAVE_REG(s2,treg); \ + SAVE_REG(s3,treg); \ + SAVE_REG(s4,treg); \ + SAVE_REG(s5,treg); \ + SAVE_REG(s6,treg); \ + SAVE_REG(s7,treg); \ + SAVE_REG(gp,treg); \ + SAVE_REG(s8,treg); \ + SAVE_REG(ra,treg); \ + sw k0, (sp_IDX * 4)(treg); \ + sw k1, (cp0_epc_IDX * 4)(treg); -#define RESTORE_INT_CONTEXT \ - lw k1, (NUM_REGISTERS * 4)(sp); \ +#define RESTORE_INT_CONTEXT(treg) \ + lw k1, (cp0_epc_IDX * 4)(treg); \ mtc0 k1, CP0_EPC; \ - LOAD_REG(s0,sp); \ - LOAD_REG(s1,sp); \ - LOAD_REG(s2,sp); \ - LOAD_REG(s3,sp); \ - LOAD_REG(s4,sp); \ - LOAD_REG(s5,sp); \ - LOAD_REG(s6,sp); \ - LOAD_REG(s7,sp); \ - LOAD_REG(v0,sp); \ - LOAD_REG(v1,sp); \ - LOAD_REG(a0,sp); \ - LOAD_REG(a1,sp); \ - LOAD_REG(a2,sp); \ - LOAD_REG(a3,sp); \ - LOAD_REG(t0,sp); \ - LOAD_REG(t1,sp); \ - LOAD_REG(t2,sp); \ - LOAD_REG(t3,sp); \ - LOAD_REG(t4,sp); \ - LOAD_REG(t5,sp); \ - LOAD_REG(t6,sp); \ - LOAD_REG(t7,sp); \ - LOAD_REG(t8,sp); \ - LOAD_REG(t9,sp); \ - LOAD_REG(gp,sp); \ - LOAD_REG(ra,sp); \ - LOAD_REG(s8,sp); \ - lw sp, (sp_IDX * 4)(sp); + LOAD_REG(s0,treg); \ + LOAD_REG(s1,treg); \ + LOAD_REG(s2,treg); \ + LOAD_REG(s3,treg); \ + LOAD_REG(s4,treg); \ + LOAD_REG(s5,treg); \ + LOAD_REG(s6,treg); \ + LOAD_REG(s7,treg); \ + LOAD_REG(v0,treg); \ + LOAD_REG(v1,treg); \ + LOAD_REG(a0,treg); \ + LOAD_REG(a1,treg); \ + LOAD_REG(a2,treg); \ + LOAD_REG(a3,treg); \ + LOAD_REG(t0,treg); \ + LOAD_REG(t1,treg); \ + LOAD_REG(t2,treg); \ + LOAD_REG(t3,treg); \ + LOAD_REG(t4,treg); \ + LOAD_REG(t5,treg); \ + LOAD_REG(t6,treg); \ + LOAD_REG(t7,treg); \ + LOAD_REG(t8,treg); \ + LOAD_REG(t9,treg); \ + LOAD_REG(gp,treg); \ + LOAD_REG(ra,treg); \ + LOAD_REG(s8,treg); \ + lw sp, (sp_IDX * 4)(treg); #endif /* __ASSEMBLY__ */ diff --git a/ports/mips/atomport-asm.s b/ports/mips/atomport-asm.s index 2b64746..931ee9e 100644 --- a/ports/mips/atomport-asm.s +++ b/ports/mips/atomport-asm.s @@ -31,9 +31,6 @@ .section .text -.extern atomCurrentContext -.extern at_preempt_count - /** * Function that performs the contextSwitch. Whether its a voluntary release * of CPU by thread or a pre-emption, under both conditions this function is @@ -43,121 +40,49 @@ */ .globl archContextSwitch archContextSwitch: - /* - * Check if we are being called in interrupt - * context. If yes, we need to restore complete - * context and return directly from here. - */ - move k0, ra - bal atomCurrentContext - nop - beq v0, zero, __in_int_context - nop - - move ra, k0 move v0, a0 /* return old tcb when we return from here */ lw k0, 0(a0) /* assume that sp_save_ptr is always at base of ATOM_TCB */ - sw s0, (s0_IDX * 4)(k0) - sw s1, (s1_IDX * 4)(k0) - sw s2, (s2_IDX * 4)(k0) - sw s3, (s3_IDX * 4)(k0) - sw s4, (s4_IDX * 4)(k0) - sw s5, (s5_IDX * 4)(k0) - sw s6, (s6_IDX * 4)(k0) - sw s7, (s7_IDX * 4)(k0) - sw s8, (s8_IDX * 4)(k0) - sw sp, (sp_IDX * 4)(k0) - sw gp, (gp_IDX * 4)(k0) - sw ra, (ra_IDX * 4)(k0) - /* - * We are saving registers in non-interrupt context because - * a thread probably is trying to yield CPU. Storing zero - * in EPC offset differentiates this. When restoring the - * context, if EPC offset has zero we will restore only - * the partial context. Rest will be done by GCC while - * unwinding the call. - */ - sw zero, (cp0_epc_IDX * 4)(k0) + SAVE_REG(s0, k0) + SAVE_REG(s1, k0) + SAVE_REG(s2, k0) + SAVE_REG(s3, k0) + SAVE_REG(s4, k0) + SAVE_REG(s5, k0) + SAVE_REG(s6, k0) + SAVE_REG(s7, k0) + SAVE_REG(s8, k0) + SAVE_REG(sp, k0) + SAVE_REG(gp, k0) + SAVE_REG(ra, k0) lw k1, 0(a1) + LOAD_REG(s0, k1) + LOAD_REG(s1, k1) + LOAD_REG(s2, k1) + LOAD_REG(s3, k1) + LOAD_REG(s4, k1) + LOAD_REG(s5, k1) + LOAD_REG(s6, k1) + LOAD_REG(s7, k1) + LOAD_REG(s8, k1) + LOAD_REG(sp, k1) + LOAD_REG(gp, k1) + LOAD_REG(ra, k1) + lw k0, (cp0_epc_IDX * 4)(k1) - bnez k0, __unwind_int_context + bnez k0, 1f nop - - lw s0, (s0_IDX * 4)(k1) - lw s1, (s1_IDX * 4)(k1) - lw s2, (s2_IDX * 4)(k1) - lw s3, (s3_IDX * 4)(k1) - lw s4, (s4_IDX * 4)(k1) - lw s5, (s5_IDX * 4)(k1) - lw s6, (s6_IDX * 4)(k1) - lw s7, (s7_IDX * 4)(k1) - lw s8, (s8_IDX * 4)(k1) - lw sp, (sp_IDX * 4)(k1) - lw gp, (gp_IDX * 4)(k1) - lw ra, (ra_IDX * 4)(k1) - + li k0, 0x00000001 + sw k0, (cp0_epc_IDX * 4)(k1) + LOAD_REG(a0, k1) + LOAD_REG(a1, k1) + LOAD_REG(a2, k1) + LOAD_REG(a3, k1) + enable_global_interrupts +1: jr ra nop -__in_int_context: - move ra, k0 - /* - * In interrupt context, the interrupt handler - * saves the context for us. Its very well there - * and we don't need to do it again. - * - * We will figure out of the task that we are - * switching in was saved in interrupt context - * or otherwise. - */ - lw k0, (cp0_epc_IDX * 4)(k1) - bnez k0, __unwind_int_context - nop - - /* - * Unwinding a task switched in non-interrupt context. - * So, restore only the partials. But since we are in - * interrupt mode, we will put ra in epc and do a eret - * so that we get out of interrupt mode and switch to - * the new task. - */ -__unwind_non_int_context: - lw s0, (s0_IDX * 4)(k1) - lw s1, (s1_IDX * 4)(k1) - lw s2, (s2_IDX * 4)(k1) - lw s3, (s3_IDX * 4)(k1) - lw s4, (s4_IDX * 4)(k1) - lw s5, (s5_IDX * 4)(k1) - lw s6, (s6_IDX * 4)(k1) - lw s7, (s7_IDX * 4)(k1) - lw s8, (s8_IDX * 4)(k1) - lw sp, (sp_IDX * 4)(k1) - lw gp, (gp_IDX * 4)(k1) - lw ra, (ra_IDX * 4)(k1) - mtc0 ra, CP0_EPC - nop - nop - nop - j __ret_from_switch - nop - -__unwind_int_context: - move sp, k1 - RESTORE_INT_CONTEXT - -__ret_from_switch: - la k0, at_preempt_count - lw k1, (k0) - addi k1, k1, -1 - sw k1, (k0) - bnez k1, __return_from_int - nop - enable_global_interrupts - ehb -__return_from_int: - eret - /** * archFirstThreadRestore(ATOM_TCB *new_tcb) * @@ -182,5 +107,13 @@ archFirstThreadRestore: nop nop nop + ehb + li k0, 0x00000001 + sw k0, (cp0_epc_IDX * 4)(k1) + nop + ehb enable_global_interrupts + ehb + nop + nop eret diff --git a/ports/mips/atomport-entry.s b/ports/mips/atomport-entry.s index 35b5735..f38bd10 100644 --- a/ports/mips/atomport-entry.s +++ b/ports/mips/atomport-entry.s @@ -90,32 +90,16 @@ LEAF(_handle_interrupt) beq k0, zero, 1f nop - move k0, ra - move k1, v0 - bal atomCurrentContext - nop - beq v0, zero, 2f /* v0 should be current context */ - nop - - move ra, k0 - lw k0, 0(v0) - move v0, k1 - move k1, k0 - /* - * Note that we aren't loading any new SP. Context - * will be save on the interrupted threads' stack. - */ move k0, sp - move sp, k1 - SAVE_INT_CONTEXT + /* Calculate interrupt context base */ + addi sp, sp, -(NUM_CTX_REGS * WORD_SIZE) + SAVE_INT_CONTEXT(sp) bal handle_mips_systick nop - RESTORE_INT_CONTEXT -1: + RESTORE_INT_CONTEXT(sp) +1: enable_global_interrupts eret - -2: b 2b END(_handle_interrupt) LEAF(_handle_cache_error) diff --git a/ports/mips/atomport-timer.c b/ports/mips/atomport-timer.c index 3997a29..a1e2e02 100644 --- a/ports/mips/atomport-timer.c +++ b/ports/mips/atomport-timer.c @@ -54,14 +54,19 @@ void mips_cpu_timer_enable(void) void handle_mips_systick(void) { + /* clear EXL from status */ + uint32_t sr = read_c0_status(); + sr &= ~0x00000002; + write_c0_status(sr); + /* Call the interrupt entry routine */ atomIntEnter(); /* Call the OS system tick handler */ atomTimerTick(); + write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); + /* Call the interrupt exit routine */ atomIntExit(TRUE); - - write_c0_compare(read_c0_count() + COUNTER_TICK_COUNT); } diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index 0af7f71..95301a6 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -31,7 +31,7 @@ #include #include #include -#include "regs.h" +#include #include @@ -58,11 +58,11 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(UINT32), UINT32 entry_param) { - #define STORE_VAL(base, reg, val) \ *((uint32_t *)(base + ((reg ## _IDX) * WORD_SIZE))) = (uint32_t)val - uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * (NUM_REGISTERS + 1))); + /* Make space for context saving */ + uint32_t stack_start = (uint32_t)(stack_top - (WORD_SIZE * NUM_CTX_REGS)); tcb_ptr->sp_save_ptr = (void *)stack_start; @@ -75,7 +75,7 @@ void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, STORE_VAL(stack_start, s5, 0); STORE_VAL(stack_start, s6, 0); STORE_VAL(stack_start, s7, 0); - STORE_VAL(stack_start, cp0_epc, entry_point); + STORE_VAL(stack_start, cp0_epc, 0); STORE_VAL(stack_start, ra, entry_point); STORE_VAL(stack_start, a0, entry_param); } diff --git a/ports/mips/atomport.h b/ports/mips/atomport.h index b7a6832..6145df1 100644 --- a/ports/mips/atomport.h +++ b/ports/mips/atomport.h @@ -72,21 +72,14 @@ extern uint32_t at_preempt_count; __asm__ __volatile__("di %0\t\n" \ "ehb\t\n" \ :"=r"(status_reg)); \ - at_preempt_count++; \ }while(0); #define CRITICAL_END() \ do { \ - at_preempt_count--; \ - \ - if (at_preempt_count == 0) { \ - if (atomCurrentContext()) { \ - __asm__ __volatile__("ei %0\t\n" \ - "ehb\t\n" \ - ::"r"(status_reg));\ - } \ - } \ - \ + __asm__ __volatile__("mtc0 %0, $12\t\n" \ + "nop\t\n" \ + "ehb\t\n" \ + ::"r"(status_reg)); \ }while(0); /* Uncomment to enable stack-checking */ diff --git a/ports/mips/regs.h b/ports/mips/regs.h index ecf77d5..4e0d9e0 100644 --- a/ports/mips/regs.h +++ b/ports/mips/regs.h @@ -101,6 +101,10 @@ #define at_IDX 30 #define zero_IDX 31 #define cp0_epc_IDX 32 +#define cp0_status_IDX 33 +#define cp_cause_IDX 34 + +#define NUM_CTX_REGS 35 #define CP0_INDEX $0 #define CP0_RANDOM $1 From 8de14626d0a25d204b8e6ac3dc4aa3ffe8d86490 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 28 Jul 2011 22:22:52 +0100 Subject: [PATCH 65/76] Remove unnecessary mods from the MIPS pull request (kernel and tests folder changes are not required, only the MIPS port folder is necessary). --- kernel/atom.h | 2 +- kernel/atomkernel.c | 2 +- kernel/atomport-template.h | 1 + tests/kern2.c | 3 --- tests/kern3.c | 3 --- tests/kern4.c | 3 --- tests/mutex1.c | 1 + tests/mutex3.c | 3 --- tests/mutex4.c | 1 + tests/mutex5.c | 1 + tests/mutex6.c | 1 + tests/mutex8.c | 1 + tests/mutex9.c | 1 + tests/queue10.c | 1 + tests/queue2.c | 1 + tests/queue3.c | 1 + tests/queue5.c | 1 + tests/queue6.c | 1 + tests/queue7.c | 1 + tests/queue8.c | 1 + tests/queue9.c | 1 + tests/sem3.c | 1 + tests/sem4.c | 1 + tests/sem5.c | 1 + tests/sem6.c | 1 + tests/sem7.c | 1 + tests/sem8.c | 1 + tests/sem9.c | 1 + tests/test-template.c | 3 ++- tests/timer2.c | 1 + tests/timer4.c | 3 ++- tests/timer5.c | 2 ++ tests/timer6.c | 3 ++- tests/timer7.c | 1 + 34 files changed, 34 insertions(+), 17 deletions(-) diff --git a/kernel/atom.h b/kernel/atom.h index b99512d..d71acc6 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -116,7 +116,7 @@ extern ATOM_TCB *atomCurrentContext (void); extern uint8_t atomThreadCreate (ATOM_TCB *tcb_ptr, uint8_t priority, void (*entry_point)(uint32_t), uint32_t entry_param, void *stack_bottom, uint32_t stack_size, uint8_t stack_check); extern uint8_t atomThreadStackCheck (ATOM_TCB *tcb_ptr, uint32_t *used_bytes, uint32_t *free_bytes); -extern ATOM_TCB *archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); +extern void archContextSwitch (ATOM_TCB *old_tcb_ptr, ATOM_TCB *new_tcb_ptr); extern void archThreadContextInit (ATOM_TCB *tcb_ptr, void *stack_top, void (*entry_point)(uint32_t), uint32_t entry_param); extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr); diff --git a/kernel/atomkernel.c b/kernel/atomkernel.c index 91d0a58..7521c70 100755 --- a/kernel/atomkernel.c +++ b/kernel/atomkernel.c @@ -343,7 +343,7 @@ static void atomThreadSwitch(ATOM_TCB *old_tcb, ATOM_TCB *new_tcb) curr_tcb = new_tcb; /* Call the architecture-specific context switch */ - old_tcb = archContextSwitch (old_tcb, new_tcb); + archContextSwitch (old_tcb, new_tcb); } /** diff --git a/kernel/atomport-template.h b/kernel/atomport-template.h index ecb07ea..9f17635 100755 --- a/kernel/atomport-template.h +++ b/kernel/atomport-template.h @@ -30,6 +30,7 @@ #ifndef __ATOM_PORT_H #define __ATOM_PORT_H + /* Required number of system ticks per second (normally 100 for 10ms tick) */ #define SYSTEM_TICKS_PER_SEC 100 diff --git a/tests/kern2.c b/tests/kern2.c index d1d1254..7387c89 100644 --- a/tests/kern2.c +++ b/tests/kern2.c @@ -31,9 +31,6 @@ #include "atom.h" #include "atomtests.h" -#ifdef STAND_ALONE -#include -#endif /** * \b test_start diff --git a/tests/kern3.c b/tests/kern3.c index 4ff1caa..a149d72 100644 --- a/tests/kern3.c +++ b/tests/kern3.c @@ -31,9 +31,6 @@ #include "atom.h" #include "atomtests.h" -#ifdef STAND_ALONE -#include -#endif /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/kern4.c b/tests/kern4.c index 2a06e95..23ed33b 100644 --- a/tests/kern4.c +++ b/tests/kern4.c @@ -31,9 +31,6 @@ #include "atom.h" #include "atomtests.h" -#ifdef STAND_ALONE -#include -#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 diff --git a/tests/mutex1.c b/tests/mutex1.c index 976a8ef..40f1a9d 100644 --- a/tests/mutex1.c +++ b/tests/mutex1.c @@ -31,6 +31,7 @@ #include "atommutex.h" #include "atomtests.h" + /* Number of test threads */ #define NUM_TEST_THREADS 2 diff --git a/tests/mutex3.c b/tests/mutex3.c index b5e83a4..958a657 100644 --- a/tests/mutex3.c +++ b/tests/mutex3.c @@ -32,9 +32,6 @@ #include "atomtests.h" #include "atommutex.h" -#ifdef STAND_ALONE -#include -#endif /* Number of test threads */ #define NUM_TEST_THREADS 4 diff --git a/tests/mutex4.c b/tests/mutex4.c index 5ecc316..6bf1281 100644 --- a/tests/mutex4.c +++ b/tests/mutex4.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex5.c b/tests/mutex5.c index 5125d96..dc31558 100644 --- a/tests/mutex5.c +++ b/tests/mutex5.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex6.c b/tests/mutex6.c index b47b7aa..6e2890e 100644 --- a/tests/mutex6.c +++ b/tests/mutex6.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/mutex8.c b/tests/mutex8.c index 9b2af5c..4892bb0 100644 --- a/tests/mutex8.c +++ b/tests/mutex8.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atommutex.h" #include "atomtests.h" diff --git a/tests/mutex9.c b/tests/mutex9.c index 36cf965..a690836 100644 --- a/tests/mutex9.c +++ b/tests/mutex9.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atommutex.h" diff --git a/tests/queue10.c b/tests/queue10.c index 0a0ff0e..ca6b6be 100644 --- a/tests/queue10.c +++ b/tests/queue10.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue2.c b/tests/queue2.c index e2ccff6..3b5f9f5 100644 --- a/tests/queue2.c +++ b/tests/queue2.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue3.c b/tests/queue3.c index dd7eb1a..8b4427e 100644 --- a/tests/queue3.c +++ b/tests/queue3.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue5.c b/tests/queue5.c index a3c15d9..4cf5dbd 100644 --- a/tests/queue5.c +++ b/tests/queue5.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue6.c b/tests/queue6.c index 68e43a2..1849b3b 100644 --- a/tests/queue6.c +++ b/tests/queue6.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue7.c b/tests/queue7.c index 061bc20..83eefa7 100644 --- a/tests/queue7.c +++ b/tests/queue7.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomqueue.h" #include "atomtests.h" diff --git a/tests/queue8.c b/tests/queue8.c index 5cfef6d..9064e47 100644 --- a/tests/queue8.c +++ b/tests/queue8.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/queue9.c b/tests/queue9.c index 0907928..d914ee9 100644 --- a/tests/queue9.c +++ b/tests/queue9.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomqueue.h" diff --git a/tests/sem3.c b/tests/sem3.c index 33e06ad..19ece62 100644 --- a/tests/sem3.c +++ b/tests/sem3.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem4.c b/tests/sem4.c index 193b1e2..128276f 100644 --- a/tests/sem4.c +++ b/tests/sem4.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem5.c b/tests/sem5.c index 6a00750..4603071 100644 --- a/tests/sem5.c +++ b/tests/sem5.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem6.c b/tests/sem6.c index 7aebda1..532ec29 100644 --- a/tests/sem6.c +++ b/tests/sem6.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem7.c b/tests/sem7.c index 337a7b5..3835103 100644 --- a/tests/sem7.c +++ b/tests/sem7.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem8.c b/tests/sem8.c index 5f2ecea..ec27ba3 100644 --- a/tests/sem8.c +++ b/tests/sem8.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" #include "atomsem.h" diff --git a/tests/sem9.c b/tests/sem9.c index f2f6c55..fe660ba 100644 --- a/tests/sem9.c +++ b/tests/sem9.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomsem.h" #include "atomtests.h" diff --git a/tests/test-template.c b/tests/test-template.c index 449af59..c306c1c 100644 --- a/tests/test-template.c +++ b/tests/test-template.c @@ -31,6 +31,7 @@ #include "atom.h" #include "atomtests.h" + /** * \b test_start * @@ -52,4 +53,4 @@ uint32_t test_start (void) /* Quit */ return failures; -} +} \ No newline at end of file diff --git a/tests/timer2.c b/tests/timer2.c index e75defc..b9cbc55 100644 --- a/tests/timer2.c +++ b/tests/timer2.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtimer.h" #include "atomtests.h" diff --git a/tests/timer4.c b/tests/timer4.c index c5c98e6..1e74e88 100644 --- a/tests/timer4.c +++ b/tests/timer4.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtimer.h" #include "atomtests.h" @@ -189,4 +190,4 @@ static void testCallback (POINTER cb_data) /* Not called at expected time, don't clear the location */ } -} +} \ No newline at end of file diff --git a/tests/timer5.c b/tests/timer5.c index 0082a47..080a5b8 100644 --- a/tests/timer5.c +++ b/tests/timer5.c @@ -27,11 +27,13 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomsem.h" #include "atomtimer.h" #include "atomtests.h" + /* Global test data */ static volatile int callback_ran_flag; diff --git a/tests/timer6.c b/tests/timer6.c index 23fa557..da7f0da 100644 --- a/tests/timer6.c +++ b/tests/timer6.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtimer.h" #include "atomtests.h" @@ -151,4 +152,4 @@ static void testCallback (POINTER cb_data) { /* Callback was called */ *(int *)cb_data = TRUE; -} +} \ No newline at end of file diff --git a/tests/timer7.c b/tests/timer7.c index 7da3b85..d2a7e54 100644 --- a/tests/timer7.c +++ b/tests/timer7.c @@ -27,6 +27,7 @@ * POSSIBILITY OF SUCH DAMAGE. */ + #include "atom.h" #include "atomtests.h" From 511187c7bd8dcb6fd0d637ad80df916e1a1e68f2 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 28 Jul 2011 22:26:43 +0100 Subject: [PATCH 66/76] Use consistent include formatting. --- ports/mips/atomport.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/ports/mips/atomport.c b/ports/mips/atomport.c index 95301a6..ca1c848 100644 --- a/ports/mips/atomport.c +++ b/ports/mips/atomport.c @@ -28,11 +28,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include -#include -#include -#include -#include +#include "atom.h" +#include "atomport-private.h" +#include "atomport.h" +#include "atomport-asm-macros.h" +#include "string.h" /* Used for managing nesting of atomport.h critical sections */ From 49f27eff8d6df1532d405367fd0e630296440962 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 29 Jul 2011 09:31:06 +0530 Subject: [PATCH 67/76] Minor refactoring in the build process. Signed-off-by: Anup Patel --- ports/armv7a/Makefile | 8 ++++++-- ports/armv7a/{ => pb-a8}/linker.ld | 0 2 files changed, 6 insertions(+), 2 deletions(-) rename ports/armv7a/{ => pb-a8}/linker.ld (100%) diff --git a/ports/armv7a/Makefile b/ports/armv7a/Makefile index 6c0ec7f..b95991f 100644 --- a/ports/armv7a/Makefile +++ b/ports/armv7a/Makefile @@ -13,8 +13,12 @@ endif src_dir=$(CURDIR) # Configuration +ifndef CPU CPU=cortex-a8 +endif +ifndef BOARD BOARD=pb-a8 +endif CC=$(CROSS_COMPILE)gcc OBJCOPY=$(CROSS_COMPILE)objcopy # Enable stack-checking. WARNING: the full automated test suite currently @@ -107,10 +111,10 @@ $(build_dir)/%.bin: $(build_dir)/%.elf $(if $(V), @echo " (OBJCOPY) $(subst $(build_dir)/,,$@)") $(V)$(OBJCOPY) -O binary $< $@ -$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) +$(build_dir)/%.elf: $(build_dir)/%.o $(build_objs) $(board_dir)/linker.ld $(V)mkdir -p `dirname $@` $(if $(V), @echo " (ELF) $(subst $(build_dir)/,,$@)") - $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T linker.ld -o $@ + $(V)$(CC) $(CFLAGS) $(build_objs) $< -static-libgcc -lgcc -Wl -T $(board_dir)/linker.ld -o $@ $(build_dir)/%.o: $(src_dir)/%.S $(V)mkdir -p `dirname $@` diff --git a/ports/armv7a/linker.ld b/ports/armv7a/pb-a8/linker.ld similarity index 100% rename from ports/armv7a/linker.ld rename to ports/armv7a/pb-a8/linker.ld From b812419f4a40400e9d54dab6c04fefc081817f63 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Mon, 1 Aug 2011 01:11:34 +0100 Subject: [PATCH 68/76] README: Add instructions for creating armv7a boards. --- ports/armv7a/README | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 ports/armv7a/README diff --git a/ports/armv7a/README b/ports/armv7a/README new file mode 100644 index 0000000..eaa4f2e --- /dev/null +++ b/ports/armv7a/README @@ -0,0 +1,12 @@ +CROSS_COMPILE=/opt/arm-2009q3/bin/arm-none-eabi- +export CROSS_COMPILE + +qemu-system-arm -M realview-pb-a8 -serial stdio -kernel build/kern2.elf + +Following are the steps to add new board under armv7a port: +1. Create a directory under ports/armv7a with name +2. Add linker.ld in ports/armv7a/ (similar to the one in ports/armv7a/pb-a8) +3. Add arm_pic.h, arm_timer.h, and arm_uart.h in ports/armv7a/ (similar to the one in ports/armv7a/pb-a8) +4. Add .c files in ports/armv7a/ to implement the board specific functions expected in arm_pic.h, arm_timer.h, and arm_uart.h +5. Add Makefile in ports/armv7a/ (similar to the one in ports/armv7a/pb-a8) to build board specific objects corresponding to the .c files added in step 4. +5. To build atomthreads for board use following command "make BOARD=" with ports/armv7a as current directory. From 22a5af0eae2302ee43b0ed51b3b815bf40f79c44 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 16 Sep 2011 22:55:40 +0100 Subject: [PATCH 69/76] Use near_func to work with later versions of IAR EWSTM8 (1.20+). Project files upgraded to EWSTM8 1.30. --- ports/stm8/atomport-asm-iar.s | 2 +- ports/stm8/atomthreads-sample-iar.ewd | 68 +++++++++++++++++++++++---- ports/stm8/atomthreads-sample-iar.ewp | 44 +++++++++++------ 3 files changed, 89 insertions(+), 25 deletions(-) diff --git a/ports/stm8/atomport-asm-iar.s b/ports/stm8/atomport-asm-iar.s index dc7c286..1c79d1d 100644 --- a/ports/stm8/atomport-asm-iar.s +++ b/ports/stm8/atomport-asm-iar.s @@ -32,7 +32,7 @@ NAME ATOMPORTASM - SECTION .text:code + SECTION .near_func.text:code ; Get definitions for virtual registers used by the compiler #include "vregs.inc" diff --git a/ports/stm8/atomthreads-sample-iar.ewd b/ports/stm8/atomthreads-sample-iar.ewd index 5dc3141..9858dbd 100644 --- a/ports/stm8/atomthreads-sample-iar.ewd +++ b/ports/stm8/atomthreads-sample-iar.ewd @@ -12,7 +12,7 @@ C-SPY 1 - 0 + 1 1 1 + + + + + + @@ -161,6 +185,10 @@ + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin 1 @@ -169,10 +197,6 @@ $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 - - $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin 1 @@ -193,7 +217,7 @@ C-SPY 1 - 0 + 1 1 0 + + + + + + @@ -342,6 +390,10 @@ + + $TOOLKIT_DIR$\plugins\rtos\embOS\embOSPlugin.ewplugin + 0 + $EW_DIR$\common\plugins\CodeCoverage\CodeCoverage.ENU.ewplugin 1 @@ -350,10 +402,6 @@ $EW_DIR$\common\plugins\Orti\Orti.ENU.ewplugin 0 - - $EW_DIR$\common\plugins\Profiling\Profiling.ENU.ewplugin - 1 - $EW_DIR$\common\plugins\Stack\Stack.ENU.ewplugin 1 diff --git a/ports/stm8/atomthreads-sample-iar.ewp b/ports/stm8/atomthreads-sample-iar.ewp index ae76bf8..8a8d48a 100644 --- a/ports/stm8/atomthreads-sample-iar.ewp +++ b/ports/stm8/atomthreads-sample-iar.ewp @@ -10,7 +10,7 @@ 1 General - 1 + 2 1 1 @@ -115,7 +115,7 @@ ICCSTM8 - 1 + 2 8 1 @@ -306,7 +306,7 @@ ASTM8 - 1 + 2 1 1 @@ -499,9 +499,9 @@ ILINK - 1 + 2 - 0 + 1 1 1 + + IARCHIVE - 1 + 2 0 1 @@ -760,7 +768,7 @@ 0 General - 1 + 2 1 1 @@ -865,7 +873,7 @@ ICCSTM8 - 1 + 2 8 1 @@ -1056,7 +1064,7 @@ ASTM8 - 1 + 2 1 1 @@ -1249,9 +1257,9 @@ ILINK - 1 + 2 - 0 + 1 1 0 + + IARCHIVE - 1 + 2 0 1 @@ -2332,7 +2348,7 @@ $PROJ_DIR$\stm8s-periphs\stm8s_clk.c - $PROJ_DIR$\stm8s-periphs\stm8s_clk.h + $PROJ_DIR$\STM8S-PERIPHS\stm8s_clk.h $PROJ_DIR$\stm8s-periphs\stm8s_gpio.c @@ -2359,7 +2375,7 @@ $PROJ_DIR$\STM8S-PERIPHS\stm8s_uart2.c - $PROJ_DIR$\stm8s-periphs\stm8s_uart2.h + $PROJ_DIR$\STM8S-PERIPHS\stm8s_uart2.h Debug From 97a15799b4f8d464e006f1c25546798cd4f385f6 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 21 Jun 2012 21:29:18 +0100 Subject: [PATCH 70/76] AVR port: instructions for using PART= to change the CPU target during make. Also add TESTS_LOG_STACK parameter so that stack-usage logging can be enabled without editing Makefile. --- ports/avr/Makefile | 8 +++++++- ports/avr/README | 23 ++++++++++++++--------- 2 files changed, 21 insertions(+), 10 deletions(-) diff --git a/ports/avr/Makefile b/ports/avr/Makefile index 7fdb5c4..17d7d74 100644 --- a/ports/avr/Makefile +++ b/ports/avr/Makefile @@ -28,6 +28,9 @@ PART=atmega16 # must disable stack-checking to run all of the automated tests. #STACK_CHECK=true +# Test programs: Log stack usage to UART (if STACK_CHECK is enabled) +#TESTS_LOG_STACK=true + # Directory for built objects BUILD_DIR=build @@ -57,10 +60,13 @@ vpath %.hex ./$(BUILD_DIR) # GCC flags CFLAGS=-g -mmcu=$(PART) -Wall -Werror -# Enable stack-checking (disable if not required) +# Enable stack-checking options (disable if not required) ifeq ($(STACK_CHECK),true) CFLAGS += -DATOM_STACK_CHECKING endif +ifeq ($(TESTS_LOG_STACK),true) +CFLAGS += -DTESTS_LOG_STACK_USAGE +endif ################# diff --git a/ports/avr/README b/ports/avr/README index e73fa4c..37413e3 100644 --- a/ports/avr/README +++ b/ports/avr/README @@ -66,9 +66,10 @@ can easily replace UISP by your own favourite programmer if required. BUILDING THE SOURCE A Makefile is provided for building the kernel, port and automated tests. -The full build is carried out using simply: +The full build is carried out using the following (replacing PART by the +ATmega device you are using): - * make + * make PART=atmega128 All objects are built into the 'build' folder under ports/avr. The build process builds separate target applications for each automated test, and @@ -96,11 +97,12 @@ PROGRAMMING TO THE TARGET DEVICE Application HEX files which are built into the build folder can be downloaded to the target using: - * make program app= + * make PART= program app= -For example to download the 'sem1.hex' test application to the target use: +For example to download the 'sem1.hex' test application to an ATmega128 +target use: - * make program app=sem1 + * make PART=atmega128 program app=sem1 This uses UISP which will write the application into flash and reset the CPU to start running the program automatically. @@ -143,11 +145,11 @@ The full set of tests can be found in the top-level 'tests' folder. Each of these tests is built as an independent application in the 'build' folder. Run them individually using: - * make program app=testname + * make PART= program app= -For example to run the 'kern1.c' test use: +For example to run the 'kern1.c' test on an ATmega128 device use: - * make program app=kern1 + * make PART=atmega128 program app=kern1 Before running the program and data size for the application is printed out on the terminal. You can use this to verify that your platform has @@ -204,7 +206,10 @@ a call to your own application startup code. PORTING TO OTHER HARDWARE PLATFORMS If you are using a CPU other than the ATmega16, change the PART definition -in the Makefile to your own CPU. +in the Makefile to your own CPU, or specify the PART on the make command +line using: + + * make PART=atmega128 On CPUs with multiple UARTs, the port uses UART0 to output debug information. If you wish to use an alternative UART you may change the From b47b9697a59dd501fed05edefd661e02a4d12b31 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 21 Jun 2012 22:39:25 +0100 Subject: [PATCH 71/76] AVR: Add expect script to run test in simavr and check for success. --- ports/avr/run_test.exp | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100755 ports/avr/run_test.exp diff --git a/ports/avr/run_test.exp b/ports/avr/run_test.exp new file mode 100755 index 0000000..7adacad --- /dev/null +++ b/ports/avr/run_test.exp @@ -0,0 +1,31 @@ +#!/usr/bin/env expect + +# Start the test (arguments: ) +spawn [lindex $argv 0] -m [lindex $argv 1] [lindex $argv 2] + +# Expect to see the test starting within 10 seconds +set timeout 10 + +# Wait for the test to start ("Go..") +expect { + "Go.." { + puts "Test started" + + # The test could take up to 3 minutes to complete once started + set timeout 180 + + # Now expect to see "Pass.." or "Fail" within 3 minutes + expect { + "Pass.." { puts "Test passed"; exit 0 } + "Fail" { puts "Test failed"; exit 1 } + timeout { puts "Test timed out without completing"; exit 1 } + } + } + + timeout { + # Didn't receive "Go.." within 10 seconds + puts "Test failed to start ('Go' not seen)" + exit 1 + } +} + From 7ce220e42fed5f6aaa9b0be426dbb08554962502 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 21 Jun 2012 22:41:53 +0100 Subject: [PATCH 72/76] AVR expect script for test runs: Add description header. --- ports/avr/run_test.exp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/ports/avr/run_test.exp b/ports/avr/run_test.exp index 7adacad..0bb59db 100755 --- a/ports/avr/run_test.exp +++ b/ports/avr/run_test.exp @@ -1,6 +1,14 @@ #!/usr/bin/env expect -# Start the test (arguments: ) +# Expect script to run an automated test within the AVR simulator (simavr) and +# check for successful completion. +# +# Arguments: +# +# Returns 0 on successful test run within AVR simulator, 1 on failure + + +# Start the test spawn [lindex $argv 0] -m [lindex $argv 1] [lindex $argv 2] # Expect to see the test starting within 10 seconds From 6ce391f581f39d70c4a63b63aae4962a1f13453d Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Thu, 21 Jun 2012 23:32:44 +0100 Subject: [PATCH 73/76] AVR port: introduce simulator for all automated tests, allowing the full test suite to be run within a simulator for continuous integration. --- ports/avr/Makefile | 9 +++++++++ ports/avr/README | 33 ++++++++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/ports/avr/Makefile b/ports/avr/Makefile index 17d7d74..932ad83 100644 --- a/ports/avr/Makefile +++ b/ports/avr/Makefile @@ -15,6 +15,7 @@ CC=/usr/bin/avr-gcc OBJCOPY=/usr/bin/avr-objcopy SIZE=/usr/bin/avr-size UISP=/usr/bin/uisp +SIMAVR=/tmp/run_avr # Modify this to the device name of the UART used for UISP UISP_DEV=/dev/ttyUSB0 @@ -121,6 +122,14 @@ program : $(BUILD_DIR)/$(app).hex $(SIZE) -C --mcu=$(PART) $(BUILD_DIR)/$(app).elf $(UISP) -dprog=stk500 -dserial=$(UISP_DEV) -dpart=$(PART) --erase --upload --verify if=$(BUILD_DIR)/$(app).hex +# Generate Doxygen documentation doxygen: doxygen $(KERNEL_DIR)/Doxyfile doxygen ./Doxyfile + +# Run tests within simavr simulator +phony_sim_elfs = $(addsuffix .sim, $(TEST_ELFS)) +simtests: $(phony_sim_elfs) +.PHONY: simtests $(phony_sim_elfs) +$(phony_sim_elfs): + ./run_test.exp $(SIMAVR) $(PART) $(BUILD_DIR)/$(basename $@) diff --git a/ports/avr/README b/ports/avr/README index 37413e3..059f3cb 100644 --- a/ports/avr/README +++ b/ports/avr/README @@ -37,7 +37,9 @@ A couple of additional source files are also included here: Atomthreads includes a suite of automated tests which prove the key OS functionality, and can be used with any architecture ports. This port provides an easy mechanism for building, downloading and running the test -suite to prove the OS on your target. +suite to prove the OS on your target. You may also use the simavr +simulator to run the entire test suite and prove the OS without real +hardware. The port was carried out and tested on both an ATmega16 and ATmega32 running within an STK500 board, utilising the gcc-avr tools. It is possible @@ -190,6 +192,35 @@ the OS, creates a main thread, and calls out to the test modules. It also initialises the UART driver and redirects stdout via the UART. +--------------------------------------------------------------------------- + +RUNNING TESTS WITHIN THE SIMAVR SIMULATOR + +It is also possible to run the full automated test suite in a simulator +without programming the test applications into real hardware. This is very +useful for quick verification of the entire test suite after making any +software changes, and is much faster than download each test application to +a real target. + +A single command runs every single test application, and checks the +(simulated) UART output to verify that each test case passes. + +This requires two applications on your development PC: expect and the +simavr simulator. You can edit the SIMAVR variable in the Makefile to point +it at the simavr install location on your PC and then run: + + * make PART=atmega128 simtests + +This will run every single test application within the simulator and quit +immediately if any one test fails. You should pick an ATmega device that is +supported by the simavr simulator: atmega128 is a good choice. + +The ability to run these automated tests in one command (and without real +hardware) allows you to easily include the OS test suite in your nightly +build or continous integration system and quickly find out if any of your +local changes have caused any of the operating system tests to fail. + + --------------------------------------------------------------------------- WRITING APPLICATIONS From 43df30809c55a4bba379c199ae90282e2a78faca Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 22 Jun 2012 01:23:53 +0100 Subject: [PATCH 74/76] STM8: Correct pinout for UART. --- ports/stm8/README-COSMIC | 2 +- ports/stm8/README-IAR | 2 +- ports/stm8/README-RAISONANCE | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ports/stm8/README-COSMIC b/ports/stm8/README-COSMIC index 94e2bc5..c77d813 100644 --- a/ports/stm8/README-COSMIC +++ b/ports/stm8/README-COSMIC @@ -237,8 +237,8 @@ To connect a serial cable to the Discovery you will need to connect to the following pins on the external connectors: Vcc: CN2 pin 8 GND: CN2 pin 7 + UART RX: CN4 pin 11 (connect to TX at the PC end) UART TX: CN4 pin 10 (connect to RX at the PC end) - UART RX: CN4 pin 9 (connect to TX at the PC end) Note that the board uses TTL levels so you may need to use a level converter. External level converters may need to be powered using a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery. diff --git a/ports/stm8/README-IAR b/ports/stm8/README-IAR index 9225e07..c535fb1 100644 --- a/ports/stm8/README-IAR +++ b/ports/stm8/README-IAR @@ -213,8 +213,8 @@ To connect a serial cable to the Discovery you will need to connect to the following pins on the external connectors: Vcc: CN2 pin 8 GND: CN2 pin 7 + UART RX: CN4 pin 11 (connect to TX at the PC end) UART TX: CN4 pin 10 (connect to RX at the PC end) - UART RX: CN4 pin 9 (connect to TX at the PC end) Note that the board uses TTL levels so you may need to use a level converter. External level converters may need to be powered using a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery. diff --git a/ports/stm8/README-RAISONANCE b/ports/stm8/README-RAISONANCE index c99b90c..5ae8226 100644 --- a/ports/stm8/README-RAISONANCE +++ b/ports/stm8/README-RAISONANCE @@ -229,8 +229,8 @@ To connect a serial cable to the Discovery you will need to connect to the following pins on the external connectors: Vcc: CN2 pin 8 GND: CN2 pin 7 + UART RX: CN4 pin 11 (connect to TX at the PC end) UART TX: CN4 pin 10 (connect to RX at the PC end) - UART RX: CN4 pin 9 (connect to TX at the PC end) Note that the board uses TTL levels so you may need to use a level converter. External level converters may need to be powered using a Vdd of 5v, which can be achieved by positioning JP1 on the Discovery. From 34e989424f220ee017e497a07eeb7bf033ab3184 Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 13 Jul 2012 22:13:21 +0100 Subject: [PATCH 75/76] Add extern "C" modifiers to main public header files for mixing C/C++. Minor modifications to pull request from @bacek. --- kernel/atom.h | 7 +++++++ kernel/atommutex.h | 8 ++++++++ kernel/atomqueue.h | 8 ++++++++ kernel/atomsem.h | 8 ++++++++ kernel/atomtimer.h | 8 ++++++++ 5 files changed, 39 insertions(+) diff --git a/kernel/atom.h b/kernel/atom.h index d71acc6..ed50fcd 100755 --- a/kernel/atom.h +++ b/kernel/atom.h @@ -30,6 +30,10 @@ #ifndef __ATOM_H #define __ATOM_H +#ifdef __cplusplus +extern "C" { +#endif + #include "atomtimer.h" #include "atomport.h" @@ -122,5 +126,8 @@ extern void archFirstThreadRestore(ATOM_TCB *new_tcb_ptr); extern void atomTimerTick (void); +#ifdef __cplusplus +} +#endif #endif /* __ATOM_H */ diff --git a/kernel/atommutex.h b/kernel/atommutex.h index ee5272b..a776f7c 100755 --- a/kernel/atommutex.h +++ b/kernel/atommutex.h @@ -29,6 +29,10 @@ #ifndef __ATOM_MUTEX_H #define __ATOM_MUTEX_H +#ifdef __cplusplus +extern "C" { +#endif + typedef struct atom_mutex { ATOM_TCB * suspQ; /* Queue of threads suspended on this mutex */ @@ -41,4 +45,8 @@ extern uint8_t atomMutexDelete (ATOM_MUTEX *mutex); extern uint8_t atomMutexGet (ATOM_MUTEX *mutex, int32_t timeout); extern uint8_t atomMutexPut (ATOM_MUTEX *mutex); +#ifdef __cplusplus +} +#endif + #endif /* __ATOM_MUTEX_H */ diff --git a/kernel/atomqueue.h b/kernel/atomqueue.h index 1bf8660..64ef242 100755 --- a/kernel/atomqueue.h +++ b/kernel/atomqueue.h @@ -29,6 +29,10 @@ #ifndef __ATOM_QUEUE_H #define __ATOM_QUEUE_H +#ifdef __cplusplus +extern "C" { +#endif + typedef struct atom_queue { ATOM_TCB * putSuspQ; /* Queue of threads waiting to send */ @@ -46,4 +50,8 @@ extern uint8_t atomQueueDelete (ATOM_QUEUE *qptr); extern uint8_t atomQueueGet (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr); extern uint8_t atomQueuePut (ATOM_QUEUE *qptr, int32_t timeout, uint8_t *msgptr); +#ifdef __cplusplus +} +#endif + #endif /* __ATOM_QUEUE_H */ diff --git a/kernel/atomsem.h b/kernel/atomsem.h index b625048..ae49365 100755 --- a/kernel/atomsem.h +++ b/kernel/atomsem.h @@ -30,6 +30,10 @@ #ifndef __ATOM_SEM_H #define __ATOM_SEM_H +#ifdef __cplusplus +extern "C" { +#endif + typedef struct atom_sem { ATOM_TCB * suspQ; /* Queue of threads suspended on this semaphore */ @@ -42,4 +46,8 @@ extern uint8_t atomSemGet (ATOM_SEM *sem, int32_t timeout); extern uint8_t atomSemPut (ATOM_SEM *sem); extern uint8_t atomSemResetCount (ATOM_SEM *sem, uint8_t count); +#ifdef __cplusplus +} +#endif + #endif /* __ATOM_SEM_H */ diff --git a/kernel/atomtimer.h b/kernel/atomtimer.h index 9c182d7..efa3bd9 100755 --- a/kernel/atomtimer.h +++ b/kernel/atomtimer.h @@ -30,6 +30,10 @@ #ifndef __ATOM_TIMER_H #define __ATOM_TIMER_H +#ifdef __cplusplus +extern "C" { +#endif + #include "atomport.h" @@ -58,4 +62,8 @@ extern uint8_t atomTimerDelay (uint32_t ticks); extern uint32_t atomTimeGet (void); extern void atomTimeSet (uint32_t new_time); +#ifdef __cplusplus +} +#endif + #endif /* __ATOM_TIMER_H */ From 5181143343bd1cd9106b37594894777ecb2bf67c Mon Sep 17 00:00:00 2001 From: Kelvin Lawson Date: Fri, 13 Jul 2012 22:20:31 +0100 Subject: [PATCH 76/76] ARMv7A Port: Add contact details for contributer to README. --- ports/armv7a/README | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ports/armv7a/README b/ports/armv7a/README index eaa4f2e..8c5f60d 100644 --- a/ports/armv7a/README +++ b/ports/armv7a/README @@ -10,3 +10,5 @@ Following are the steps to add new board under armv7a port: 4. Add .c files in ports/armv7a/ to implement the board specific functions expected in arm_pic.h, arm_timer.h, and arm_uart.h 5. Add Makefile in ports/armv7a/ (similar to the one in ports/armv7a/pb-a8) to build board specific objects corresponding to the .c files added in step 4. 5. To build atomthreads for board use following command "make BOARD=" with ports/armv7a as current directory. + +Port contributed by Anup Patel (http://brainfault.blogspot.com).