Skip to content
Snippets Groups Projects
Commit 9360df65 authored by Niklas-Nitrokey's avatar Niklas-Nitrokey
Browse files

added openMZ

parent c0cb72ac
No related branches found
No related tags found
No related merge requests found
Showing
with 2076 additions and 0 deletions
---
Language: Cpp
# BasedOnStyle: WebKit
AccessModifierOffset: -4
AlignAfterOpenBracket: DontAlign
AlignConsecutiveMacros: false
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Right
AlignOperands: false
AlignTrailingComments: false
AllowAllArgumentsOnNextLine: true
AllowAllConstructorInitializersOnNextLine: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortLambdasOnASingleLine: All
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: MultiLine
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterCaseLabel: false
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: All
BreakBeforeBraces: WebKit
BreakBeforeInheritanceComma: false
BreakInheritanceList: BeforeColon
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
BreakConstructorInitializers: BeforeComma
BreakAfterJavaFieldAnnotations: false
BreakStringLiterals: true
ColumnLimit: 0
CommentPragmas: '^ IWYU pragma:'
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 4
ContinuationIndentWidth: 4
Cpp11BracedListStyle: false
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
FixNamespaceComments: false
ForEachMacros:
- foreach
- Q_FOREACH
- BOOST_FOREACH
IncludeBlocks: Preserve
IncludeCategories:
- Regex: '^"(llvm|llvm-c|clang|clang-c)/'
Priority: 2
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
Priority: 3
- Regex: '.*'
Priority: 1
IncludeIsMainRegex: '(Test)?$'
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 4
IndentWrappedFunctionNames: false
JavaScriptQuotes: Leave
JavaScriptWrapImports: true
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 1
NamespaceIndentation: Inner
ObjCBinPackProtocolList: Auto
ObjCBlockIndentWidth: 4
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 2
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyBreakTemplateDeclaration: 10
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterCStyleCast: false
SpaceAfterLogicalNot: false
SpaceAfterTemplateKeyword: true
SpaceBeforeAssignmentOperators: true
SpaceBeforeCpp11BracedList: true
SpaceBeforeCtorInitializerColon: true
SpaceBeforeInheritanceColon: true
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Cpp11
StatementMacros:
- Q_UNUSED
- QT_REQUIRE_VERSION
TabWidth: 4
UseTab: Never
...
# Compile results
*.elf
*.map
*.hex
# Eclipse project
.cproject
.project
.settings
# ctags database
tags
This project is under three different copyright licenses:
- HexFive's license (LICENSE.HEXFIVE) for the MultiZone API (libhexfive.h).
- GPLv2 (LICENSE.GPLv2) for the kernel and drivers.
- MIT (LICENSE.MIT) for the kernel configuration.
The owner of the copyright of the source files are on the top of each file.
Files described as being under the "GNU General Public License version 2"
or simply the "GPLv2" fall under the license below.
The copyrights of the GPLv2 licensed files of the project are held by the
respective owners indicated at the top of the file.
The Free Software Foundation owns the copyright to the license below.
---------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Lesser General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License.
The file "libhexfive.h" falls under the following license.
-------------------------------------------------------------------------------------------------------
Copyright (c) 2018, Hex Five Security, Inc.
Permission to use, copy, modify, and/or distribute this software for any purpose with or without
fee is hereby granted, provided that the above copyright notice and this permission notice appear
in all copies.
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE
FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
Files described as being under the "MIT License"
or simply the "MIT" fall under the license below.
The copyrights of the MIT licensed files of the project are held by the
respective owners indicated at the top of the file.
---------------------------------------------------------------------
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Copyright 2020, Saab AB
#
# This software may be distributed and modified according to
# the terms of the MIT License.
# Note that NO WARRANTY is provided.
# See "LICENSE.MIT" for details.
#
PROGRAMS = openmz zone1 zone2
BOARD ?= fe310
BSP_DIR = $(abspath bsp/$(BOARD))
include $(BSP_DIR)/settings.mk
HEXFIVE_DIR = $(abspath libhexfive)
ELF_DIR = $(abspath elf)
HEX_DIR = $(abspath hex)
export CC=riscv64-unknown-elf-gcc
export SIZE=riscv64-unknown-elf-size
export OBJCOPY=riscv64-unknown-elf-objcopy
export OBJDUMP=riscv64-unknown-elf-objdump
.PHONY: all
all: compile
.PHONY: compile
.PHONY: clean
.PHONY: upload
ifeq ($(PROGRAM),)
compile:
for file in $(PROGRAMS) ; do \
$(MAKE) -C . compile PROGRAM=$$file ; \
done
clean:
for file in $(PROGRAMS) ; do \
$(MAKE) -C . clean PROGRAM=$$file ; \
done
upload:
for file in $(PROGRAMS) ; do \
$(MAKE) -C . upload PROGRAM=$$file ; \
done
else
PROGRAM_ELF = $(ELF_DIR)/$(PROGRAM).elf
PROGRAM_HEX = $(HEX_DIR)/$(PROGRAM).hex
compile: $(PROGRAM_ELF) $(PROGRAM_HEX)
.PHONY: $(PROGRAM_ELF)
$(PROGRAM_ELF):
mkdir -p $(ELF_DIR)
$(MAKE) -C src/$(PROGRAM) compile \
PROGRAM_ELF=$(PROGRAM_ELF) \
BSP_DIR=$(BSP_DIR) \
HEXFIVE_DIR=$(HEXFIVE_DIR)
$(PROGRAM_HEX): $(PROGRAM_ELF)
mkdir -p $(HEX_DIR)
$(OBJCOPY) -O ihex $(PROGRAM_ELF) $(PROGRAM_HEX)
upload: $(PROGRAM_HEX)
echo "loadfile $(PROGRAM_HEX)\nexit" \
| JLinkExe -device fe310 -if JTAG -speed 4000 -jtagconf -1,-1 -autoconnect 1
clean:
rm -f $(PROGRAM_ELF)
endif
# OpenMZ
OpenMZ is an open-source implementation of [HexFive's MultiZone API](https://github.com/hex-five/multizone-api).
OpenMZ is a security kernel for RISC-V processors with machine-mode and user-mode. OpenMZ partitions a system into an unlimited number of zones. Each zone has full access to eight regions of memory-mapped I/O (e.g., RAM, UART, GPIO), protected using RISC-V's physical memory protection (PMP) mechanism.
## Features
- Preemptive round-robin scheduler with a configurable time slices.
- Self-contained and open-source, written in C and assembly.
- Theoretically unlimited number of *spatially* isolated zones.
- Up to eight memory-mapped I/O regions per zone with protections defined by you.
- Support for user-mode platform-level and core-local interrupts.
- Support for user-mode exception handling.
- A secure user-mode timer interrupts emulation.
- Fast register-based inter-zone communication.
## Attacker model
- **Data attack.** A zone tries to access or modify the memory in an unauthorized manner.
- **Timing attack.** A zone tries to infer information from another zone or the kernel using timing side-channel attacks.
- **Cache attack.** A zone tries to infer information from another zone or the kernel using cache side-channel attacks.
## Kernel configuration
The kernel's configurations is in [config.h](openmz/config.h). The PMP fields `pmpcfg0` and `pmpaddr[0-8]` are configured as in RISC-V's PMP registers `pmpcfg0` and `pmpaddr0-7`. The initial program counter is stored in `regs[0]`. Interrupt mappings are stored in the `irq_handlers` field. All of these configurations options are set in `config.h`.
```C
/* ... */
/* number of zone */
#define N_ZONES 3
/* max trap code */
#define N_TRAPS 12
/* max interrupt code */
#define N_INTERRUPTS 12
/* time slice in timer cycles */
#define QUANTUM (32768 / 100)
/* Zone configuration */
/* ZONE(program counter, pmpcfg0, {pmpaddr0, ..., pmpaddr7}) */
#define ZONE_CONFIG \
ZONE(0x20020000, ..., ...) \
ZONE(0x20030000, ..., ...) \
ZONE(0x20040000, ..., ...)
/* Mapping interrupts to zones */
/* IRQ(zone id, interrupt exception code) */
#define IRQ_CONFIG IRQ(1, 11) IRQ(2, 18)
/* ... */
```
## (Potential) Future Work
- Complete formal verification - from the hardware level to source code.
- Implement `ECALL_WFI`.
- `YIELD_TO` call - allowing zones to yield their remaining time slice to a specific zone.
- An optional *temporal* isolation of zones by disabling `YIELD/WFI` calls, and immediate context switch for interrupts.
- More advanced round-robin scheduling with more configurable zone order and time slices.
- Compatibility with a secure bootloader, or a new secure bootloader.
- System call for supporting remote attestation.
- RISC-V user-interrupt extension (N extension) compatibility.
- Multicore support.
- Supervisor support.
- More memory-mapped I/O regions per zone.
- Inter-processor communication (IPC) - allowing communication with a Linux companion on a different core.
*The above list is mostly sorted by priority.*
## Example zone implementation
## Attribution
## Copyright
This project is under three different copyright licenses. HexFive's license for the MultiZone API (`libhexfive.h`), GPLv2 for the kernel and drivers, and MIT for the kernel configuration. The owner of the copyright of a source file is on the top.
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
#ifndef MACHINE_H
#define MACHINE_H
#include "csr.h"
#include <platform.h>
static inline uint64_t read_mtime(void)
{
register uint32_t lo, hi1, hi2;
do {
hi1 = CLIC.mtimeh;
lo = CLIC.mtime;
hi2 = CLIC.mtimeh;
} while (hi1 != hi2);
return (uint64_t)hi1 << 32 | lo;
}
static inline void write_mtimecmp(uint64_t val)
{
CLIC.mtimecmp = -1;
CLIC.mtimecmph = val >> 32;
CLIC.mtimecmp = val;
}
static inline void clear_cache(void)
{
// no cache clearing
}
static inline void init_hardware(void)
{
// Sets core clock frequency to 16 MHz
uint32_t pllr = 0x1;
uint32_t pllf = 0x2F;
uint32_t pllq = 0x2;
uint32_t pllsel = 0x1;
uint32_t pllrefsel = 0x1;
uint32_t pllbypass = 0x0;
PRCI.pllcfg = pllr | (pllf << 4) | (pllq << 10) | (pllsel << 16) | (pllrefsel << 17) | (pllbypass << 18);
while (!(PRCI.pllcfg >> 31))
; // wait until configuration is locked
CSRW(mcounteren, 0x1F);
CSRW(mhpmevent3, 0x0102);
}
#endif // MACHINE_H
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
rom = 0x20000000;
ram = 0x80000000;
itim = 0x8000000;
CLIC = 0x02000000;
PLIC = 0x0C000000;
PRCI = 0x10008000;
GPIO = 0x10012000;
UART0 = 0x10013000;
UART1 = 0x10023000;
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
#ifndef PLATFORM_H
#define PLATFORM_H
#include <stdint.h>
#define RTCK_FREQ 32768
#define CORECLK_FREQ 192000000
// Padding so struct fields align correctly to memory map
#define _PAD(name, start, end) char name[end - start]
typedef volatile struct clic {
uint32_t msip;
_PAD(pad1, 0x4, 0x4000);
uint32_t mtimecmp;
uint32_t mtimecmph;
_PAD(pad2, 0x4008, 0xbff8);
uint32_t mtime;
uint32_t mtimeh;
} clic_t;
typedef volatile struct plic {
_PAD(pad1, 0x0, 0x4);
uint32_t source_prio[52];
_PAD(pad2, 0xD4, 0x1000);
uint32_t pending[2];
_PAD(pad3, 0x1008, 0x2000);
uint32_t ie[2];
_PAD(pad4, 0x2008, 0x200000);
uint32_t prio_thres;
uint32_t claim_complete;
} plic_t;
typedef volatile struct gpio {
uint32_t input_val;
uint32_t input_en;
uint32_t output_val;
uint32_t output_en;
uint32_t pue;
uint32_t ds;
uint32_t rise_ie;
uint32_t rise_ip;
uint32_t fall_ie;
uint32_t fall_ip;
uint32_t high_ie;
uint32_t high_ip;
uint32_t low_ie;
uint32_t low_ip;
uint32_t iof_en;
uint32_t iof_sel;
uint32_t out_xor;
} gpio_t;
typedef volatile struct uart {
int32_t txdata;
int32_t rxdata;
uint32_t txctrl;
uint32_t rxctrl;
uint32_t ie;
uint32_t ip;
uint32_t div;
} uart_t;
typedef volatile struct prci {
uint32_t hfrosccfg;
uint32_t hfxosccfg;
uint32_t pllcfg;
uint32_t plloutdiv;
uint32_t procmoncfg;
} prci_t;
extern clic_t CLIC;
extern plic_t PLIC;
extern prci_t PRCI;
extern gpio_t GPIO;
extern uart_t UART0;
extern uart_t UART1;
#endif // PLATFORM_H
export ARCH = rv32imac
export ABI = ilp32
export CMODEL = medlow
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
#define ENTRY(x) \
.globl x; \
x:
.section .text.libhexfive
ENTRY(ECALL_YIELD)
li a7, 0 # sys call #0
ecall
ret
ENTRY(ECALL_WFI)
li a7, 1 # sys call #1
ecall
ret
ENTRY(ECALL_SEND)
#if __riscv_xlen == 32
lw a4, 12(a1) # load msg[3]
lw a3, 8(a1) # load msg[2]
lw a2, 4(a1) # load msg[1]
lw a1, 0(a1) # load msg[0]
#else
ld a2, 8(a1) # load msg[2-3]
ld a1, 0(a1) # load msg[0-1]
#endif
li a7, 2 # sys call #2
ecall
ret
ENTRY(ECALL_RECV)
mv a6, a1 # save pointer
li a7, 3 # sys call #3
ecall
beqz a0, 1f # status == 0, go to ret
#if __riscv_xlen == 32
sw a4, 12(a6) # save msg[3]
sw a3, 8(a6) # save msg[2]
sw a2, 4(a6) # save msg[1]
sw a1, 0(a6) # save msg[0]
#else
sd a2, 8(a6) # save msg[2-3]
sd a1, 0(a6) # save msg[0-1]
#endif
1: ret
ENTRY(ECALL_TRP_VECT)
li a7, 4 # sys call #4
ecall
ret
ENTRY(ECALL_IRQ_VECT)
li a7, 5 # sys call #5
ecall
ret
ENTRY(ECALL_CSRS_MIE)
li a7, 6 # sys call #6
ecall
ret
ENTRY(ECALL_CSRC_MIE)
li a7, 7 # sys call #7
ecall
ret
ENTRY(ECALL_CSRW_MTIMECMP)
li a7, 8 # sys call #8
ecall
ret
ENTRY(ECALL_CSRR_MTIME)
li a7, 9 # sys call #9
ecall
ret
ENTRY(ECALL_CSRR_MCYCLE)
li a7, 10 # sys call #10
ecall
ret
ENTRY(ECALL_CSRR_MINSTR)
li a7, 11 # sys call #11
ecall
ret
ENTRY(ECALL_CSRR_MHPMC3)
li a7, 12 # sys call #12
ecall
ret
ENTRY(ECALL_CSRR_MHPMC4)
li a7, 13 # sys call #13
ecall
ret
ENTRY(ECALL_CSRR_MISA)
li a7, 14 # sys call #14
ecall
ret
ENTRY(ECALL_CSRR_MVENDID)
li a7, 15 # sys call #15
ecall
ret
ENTRY(ECALL_CSRR_MARCHID)
li a7, 16 # sys call #16
ecall
ret
ENTRY(ECALL_CSRR_MIMPID)
li a7, 17 # sys call #17
ecall
ret
ENTRY(ECALL_CSRR_MHARTID)
li a7, 18 # sys call #18
ecall
ret
/* Copyright(C) 2018 Hex Five Security, Inc. - All Rights Reserved */
#ifndef LIBHEXFIVE_H_
#define LIBHEXFIVE_H_
#include <unistd.h>
void ECALL_YIELD();
void ECALL_WFI();
int ECALL_SEND(int, void *);
int ECALL_RECV(int, void *);
void ECALL_TRP_VECT(int, void *);
void ECALL_IRQ_VECT(int, void *);
void ECALL_CSRS_MIE();
void ECALL_CSRC_MIE();
void ECALL_CSRW_MTIMECMP(uint64_t);
uint64_t ECALL_CSRR_MTIME();
uint64_t ECALL_CSRR_MCYCLE();
uint64_t ECALL_CSRR_MINSTR();
uint64_t ECALL_CSRR_MHPMC3();
uint64_t ECALL_CSRR_MHPMC4();
uint64_t ECALL_CSRR_MISA();
uint64_t ECALL_CSRR_MVENDID();
uint64_t ECALL_CSRR_MARCHID();
uint64_t ECALL_CSRR_MIMPID();
uint64_t ECALL_CSRR_MHARTID();
#endif /* LIBHEXFIVE_H_ */
This license applies to "git-pre-commit-format" and "apply-format."
----
Copyright 2017-2018 Marco Barisione <marco@barisione.org>
Copyright 2018 Undo Ltd.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
the Software, and to permit persons to whom the Software is furnished to do so,
subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#! /bin/bash
#
# Copyright 2018 Undo Ltd.
#
# https://github.com/barisione/clang-format-hooks
# Force variable declaration before access.
set -u
# Make any failure in piped commands be reflected in the exit code.
set -o pipefail
readonly bash_source="${BASH_SOURCE[0]:-$0}"
##################
# Misc functions #
##################
function error_exit() {
for str in "$@"; do
echo -n "$str" >&2
done
echo >&2
exit 1
}
########################
# Command line parsing #
########################
function show_help() {
if [ -t 1 ] && hash tput 2> /dev/null; then
local -r b=$(tput bold)
local -r i=$(tput sitm)
local -r n=$(tput sgr0)
else
local -r b=
local -r i=
local -r n=
fi
cat << EOF
${b}SYNOPSIS${n}
To reformat git diffs:
${i}$bash_source [OPTIONS] [FILES-OR-GIT-DIFF-OPTIONS]${n}
To reformat whole files, including unchanged parts:
${i}$bash_source [-f | --whole-file] FILES${n}
${b}DESCRIPTION${n}
Reformat C or C++ code to match a specified formatting style.
This command can either work on diffs, to reformat only changed parts of
the code, or on whole files (if -f or --whole-file is used).
${b}FILES-OR-GIT-DIFF-OPTIONS${n}
List of files to consider when applying clang-format to a diff. This is
passed to "git diff" as is, so it can also include extra git options or
revisions.
For example, to apply clang-format on the changes made in the last few
revisions you could use:
${i}\$ $bash_source HEAD~3${n}
${b}FILES${n}
List of files to completely reformat.
${b}-f, --whole-file${n}
Reformat the specified files completely (including parts you didn't
change).
The fix is printed on stdout by default. Use -i if you want to modify
the files on disk.
${b}--staged, --cached${n}
Reformat only code which is staged for commit.
The fix is printed on stdout by default. Use -i if you want to modify
the files on disk.
${b}-i${n}
Reformat the code and apply the changes to the files on disk (instead
of just printing the fix on stdout).
${b}--apply-to-staged${n}
This is like specifying both --staged and -i, but the formatting
changes are also staged for commit (so you can just use "git commit"
to commit what you planned to, but formatted correctly).
${b}--style STYLE${n}
The style to use for reformatting code.
If no style is specified, then it's assumed there's a .clang-format
file in the current directory or one of its parents.
${b}--help, -h, -?${n}
Show this help.
EOF
}
# getopts doesn't support long options.
# getopt mangles stuff.
# So we parse manually...
declare positionals=()
declare has_positionals=false
declare whole_file=false
declare apply_to_staged=false
declare staged=false
declare in_place=false
declare style=file
declare ignored=()
while [ $# -gt 0 ]; do
declare arg="$1"
shift # Past option.
case "$arg" in
-h | -\? | --help )
show_help
exit 0
;;
-f | --whole-file )
whole_file=true
;;
--apply-to-staged )
apply_to_staged=true
;;
--cached | --staged )
staged=true
;;
-i )
in_place=true
;;
--style=* )
style="${arg//--style=/}"
;;
--style )
[ $# -gt 0 ] || \
error_exit "No argument for --style option."
style="$1"
shift
;;
--internal-opt-ignore-regex=* )
ignored+=("${arg//--internal-opt-ignore-regex=/}")
;;
--internal-opt-ignore-regex )
ignored+=("${arg//--internal-opt-ignore-regex=/}")
[ $# -gt 0 ] || \
error_exit "No argument for --internal-opt-ignore-regex option."
ignored+=("$1")
shift
;;
-- )
# Stop processing further arguments.
if [ $# -gt 0 ]; then
positionals+=("$@")
has_positionals=true
fi
break
;;
-* )
error_exit "Unknown argument: $arg"
;;
*)
positionals+=("$arg")
;;
esac
done
# Restore positional arguments, access them from "$@".
if [ ${#positionals[@]} -gt 0 ]; then
set -- "${positionals[@]}"
has_positionals=true
fi
[ -n "$style" ] || \
error_exit "If you use --style you need to specify a valid style."
#######################################
# Detection of clang-format & friends #
#######################################
# clang-format.
declare format="${CLANG_FORMAT:-}"
if [ -z "$format" ]; then
format=$(type -p clang-format)
fi
if [ -z "$format" ]; then
error_exit \
$'You need to install clang-format.\n' \
$'\n' \
$'On Ubuntu/Debian this is available in the clang-format package or, in\n' \
$'older distro versions, clang-format-VERSION.\n' \
$'On Fedora it\'s available in the clang package.\n' \
$'You can also specify your own path for clang-format by setting the\n' \
$'$CLANG_FORMAT environment variable.'
fi
# clang-format-diff.
if [ "$whole_file" = false ]; then
invalid="/dev/null/invalid/path"
if [ "${OSTYPE:-}" = "linux-gnu" ]; then
readonly sort_version=-V
else
# On macOS, sort doesn't have -V.
readonly sort_version=-n
fi
declare paths_to_try=()
# .deb packages directly from upstream.
# We try these first as they are probably newer than the system ones.
while read -r f; do
paths_to_try+=("$f")
done < <(compgen -G "/usr/share/clang/clang-format-*/clang-format-diff.py" | sort "$sort_version" -r)
# LLVM official releases (just untarred in /usr/local).
while read -r f; do
paths_to_try+=("$f")
done < <(compgen -G "/usr/local/clang+llvm*/share/clang/clang-format-diff.py" | sort "$sort_version" -r)
# Maybe it's in the $PATH already? This is true for Ubuntu and Debian.
paths_to_try+=( \
"$(type -p clang-format-diff 2> /dev/null || echo "$invalid")" \
"$(type -p clang-format-diff.py 2> /dev/null || echo "$invalid")" \
)
# Fedora.
paths_to_try+=( \
/usr/share/clang/clang-format-diff.py \
)
# Gentoo.
while read -r f; do
paths_to_try+=("$f")
done < <(compgen -G "/usr/lib/llvm/*/share/clang/clang-format-diff.py" | sort -n -r)
# Homebrew.
while read -r f; do
paths_to_try+=("$f")
done < <(compgen -G "/usr/local/Cellar/clang-format/*/share/clang/clang-format-diff.py" | sort -n -r)
declare format_diff=
# Did the user specify a path?
if [ -n "${CLANG_FORMAT_DIFF:-}" ]; then
format_diff="$CLANG_FORMAT_DIFF"
else
for path in "${paths_to_try[@]}"; do
if [ -e "$path" ]; then
# Found!
format_diff="$path"
if [ ! -x "$format_diff" ]; then
format_diff="python $format_diff"
fi
break
fi
done
fi
if [ -z "$format_diff" ]; then
error_exit \
$'Cannot find clang-format-diff which should be shipped as part of the same\n' \
$'package where clang-format is.\n' \
$'\n' \
$'Please find out where clang-format-diff is in your distro and report an issue\n' \
$'at https://github.com/barisione/clang-format-hooks/issues with details about\n' \
$'your operating system and setup.\n' \
$'\n' \
$'You can also specify your own path for clang-format-diff by setting the\n' \
$'$CLANG_FORMAT_DIFF environment variable, for instance:\n' \
$'\n' \
$' CLANG_FORMAT_DIFF="python /.../clang-format-diff.py" \\\n' \
$' ' "$bash_source"
fi
readonly format_diff
fi
############################
# Actually run the command #
############################
if [ "$whole_file" = true ]; then
[ "$has_positionals" = true ] || \
error_exit "No files to reformat specified."
[ "$staged" = false ] || \
error_exit "--staged/--cached only make sense when applying to a diff."
read -r -a format_args <<< "$format"
format_args+=("-style=file")
[ "$in_place" = true ] && format_args+=("-i")
"${format_args[@]}" "$@"
else # Diff-only.
if [ "$apply_to_staged" = true ]; then
[ "$staged" = false ] || \
error_exit "You don't need --staged/--cached with --apply-to-staged."
[ "$in_place" = false ] || \
error_exit "You don't need -i with --apply-to-staged."
staged=true
readonly patch_dest=$(mktemp)
trap '{ rm -f "$patch_dest"; }' EXIT
else
readonly patch_dest=/dev/stdout
fi
declare git_args=(git diff -U0 --no-color)
[ "$staged" = true ] && git_args+=("--staged")
# $format_diff may contain a command ("python") and the script to excute, so we
# need to split it.
read -r -a format_diff_args <<< "$format_diff"
[ "$in_place" = true ] && format_diff_args+=("-i")
# Build the regex for paths to consider or ignore.
# We use negative lookahead assertions which preceed the list of allowed patterns
# (that is, the extensions we want).
exclusions_regex=
if [ "${#ignored[@]}" -gt 0 ]; then
for pattern in "${ignored[@]}"; do
exclusions_regex="$exclusions_regex(?!$pattern)"
done
fi
"${git_args[@]}" "$@" \
| "${format_diff_args[@]}" \
-p1 \
-style="$style" \
-iregex="$exclusions_regex"'.*\.(c|cpp|cxx|cc|h|hpp|m|mm|js|java)' \
> "$patch_dest" \
|| exit 1
if [ "$apply_to_staged" = true ]; then
if [ ! -s "$patch_dest" ]; then
echo "No formatting changes to apply."
exit 0
fi
patch -p0 < "$patch_dest" || \
error_exit "Cannot apply fix to local files."
git apply -p0 --cached < "$patch_dest" || \
error_exit "Cannot apply fix to git staged changes."
fi
fi
#! /bin/bash
#
# Copyright 2018 Undo Ltd.
#
# https://github.com/barisione/clang-format-hooks
# Force variable declaration before access.
set -u
# Make any failure in piped commands be reflected in the exit code.
set -o pipefail
readonly bash_source="${BASH_SOURCE[0]:-$0}"
if [ -t 1 ] && hash tput 2> /dev/null; then
readonly b=$(tput bold)
readonly i=$(tput sitm)
readonly n=$(tput sgr0)
else
readonly b=
readonly i=
readonly n=
fi
function error_exit() {
for str in "$@"; do
echo -n "$b$str$n" >&2
done
echo >&2
exit 1
}
# realpath is not available everywhere.
function realpath() {
if [ "${OSTYPE:-}" = "linux-gnu" ]; then
readlink -m "$@"
else
# Python should always be available on macOS.
# We use sys.stdout.write instead of print so it's compatible with both Python 2 and 3.
python -c "import sys; import os.path; sys.stdout.write(os.path.realpath('''$1''') + '\\n')"
fi
}
# realpath --relative-to is only available on recent Linux distros.
# This function behaves identical to Python's os.path.relpath() and doesn't need files to exist.
function rel_realpath() {
local -r path=$(realpath "$1")
local -r rel_to=$(realpath "${2:-$PWD}")
# Split the paths into components.
IFS='/' read -r -a path_parts <<< "$path"
IFS='/' read -r -a rel_to_parts <<< "$rel_to"
# Search for the first different component.
for ((idx=1; idx<${#path_parts[@]}; idx++)); do
if [ "${path_parts[idx]}" != "${rel_to_parts[idx]:-}" ]; then
break
fi
done
result=()
# Add the required ".." to the $result array.
local -r first_different_idx="$idx"
for ((idx=first_different_idx; idx<${#rel_to_parts[@]}; idx++)); do
result+=("..")
done
# Add the required components from $path.
for ((idx=first_different_idx; idx<${#path_parts[@]}; idx++)); do
result+=("${path_parts[idx]}")
done
if [ "${#result[@]}" -gt 0 ]; then
# Join the array with a "/" as separator.
echo "$(export IFS='/'; echo "${result[*]}")"
else
echo .
fi
}
# Find the top-level git directory (taking into account we could be in a submodule).
declare git_test_dir=.
declare top_dir
while true; do
top_dir=$(git -C "$git_test_dir" rev-parse --show-toplevel) || \
error_exit "You need to be in the git repository to run this script."
# Try to handle git worktree.
# The best way to deal both with git submodules and worktrees would be to
# use --show-superproject-working-tree, but it's not supported in git 2.7.4
# which is shipped in Ubuntu 16.04.
declare git_common_dir
if git_common_dir=$(git -C "$git_test_dir" rev-parse --git-common-dir 2>/dev/null); then
# The common dir could be relative, so we make it absolute.
git_common_dir=$(cd "$git_test_dir" && realpath "$git_common_dir")
declare maybe_top_dir
maybe_top_dir=$(realpath "$git_common_dir/..")
if [ -e "$maybe_top_dir/.git" ]; then
# We are not in a submodules, otherwise common dir would have been
# something like PROJ/.git/modules/SUBMODULE and there would not be
# a .git directory in PROJ/.git/modules/.
top_dir="$maybe_top_dir"
fi
fi
[ -e "$top_dir/.git" ] || \
error_exit "No .git directory in $top_dir."
if [ -d "$top_dir/.git" ]; then
# We are done! top_dir is the root git directory.
break
elif [ -f "$top_dir/.git" ]; then
# We are in a submodule.
git_test_dir="$git_test_dir/.."
fi
done
readonly top_dir
hook_path="$top_dir/.git/hooks/pre-commit"
readonly hook_path
me=$(realpath "$bash_source") || exit 1
readonly me
me_relative_to_hook=$(rel_realpath "$me" "$(dirname "$hook_path")") || exit 1
readonly me_relative_to_hook
my_dir=$(dirname "$me") || exit 1
readonly my_dir
apply_format="$my_dir/apply-format"
readonly apply_format
apply_format_relative_to_top_dir=$(rel_realpath "$apply_format" "$top_dir") || exit 1
readonly apply_format_relative_to_top_dir
function is_installed() {
if [ ! -e "$hook_path" ]; then
echo nothing
else
existing_hook_target=$(realpath "$hook_path") || exit 1
readonly existing_hook_target
if [ "$existing_hook_target" = "$me" ]; then
# Already installed.
echo installed
else
# There's a hook, but it's not us.
echo different
fi
fi
}
function install() {
if ln -s "$me_relative_to_hook" "$hook_path" 2> /dev/null; then
echo "Pre-commit hook installed."
else
local -r res=$(is_installed)
if [ "$res" = installed ]; then
error_exit "The hook is already installed."
elif [ "$res" = different ]; then
error_exit "There's already an existing pre-commit hook, but for something else."
elif [ "$res" = nothing ]; then
error_exit "There's no pre-commit hook, but we couldn't create a symlink."
else
error_exit "Unexpected failure."
fi
fi
}
function uninstall() {
local -r res=$(is_installed)
if [ "$res" = installed ]; then
rm "$hook_path" || \
error_exit "Couldn't remove the pre-commit hook."
elif [ "$res" = different ]; then
error_exit "There's a pre-commit hook installed, but for something else. Not removing."
elif [ "$res" = nothing ]; then
error_exit "There's no pre-commit hook, nothing to uninstall."
else
error_exit "Unexpected failure detecting the pre-commit hook status."
fi
}
function show_help() {
cat << EOF
${b}SYNOPSIS${n}
$bash_source [install|uninstall]
${b}DESCRIPTION${n}
Git hook to verify and fix formatting before committing.
The script is invoked automatically when you commit, so you need to call it
directly only to set up the hook or remove it.
To setup the hook run this script passing "install" on the command line.
To remove the hook run passing "uninstall".
${b}CONFIGURATION${n}
You can configure the hook using the "git config" command.
${b}hooks.clangFormatDiffInteractive${n} (default: true)
By default, the hook requires user input. If you don't run git from a
terminal, you can disable the interactive prompt with:
${i}\$ git config hooks.clangFormatDiffInteractive false${n}
${b}hooks.clangFormatDiffStyle${n} (default: file)
Unless a different style is specified, the hook expects a file named
.clang-format to exist in the repository. This file should contain the
configuration for clang-format.
You can specify a different style (in this example, the WebKit one)
with:
${i}\$ git config hooks.clangFormatDiffStyle WebKit${n}
EOF
}
if [ $# = 1 ]; then
case "$1" in
-h | -\? | --help )
show_help
exit 0
;;
install )
install
exit 0
;;
uninstall )
uninstall
exit 0
;;
esac
fi
[ $# = 0 ] || error_exit "Invalid arguments: $*"
# This is a real run of the hook, not a install/uninstall run.
if [ -z "${GIT_DIR:-}" ] && [ -z "${GIT_INDEX_FILE:-}" ]; then
error_exit \
$'It looks like you invoked this script directly, but it\'s supposed to be used\n' \
$'as a pre-commit git hook.\n' \
$'\n' \
$'To install the hook try:\n' \
$' ' "$bash_source" $' install\n' \
$'\n' \
$'For more details on this script try:\n' \
$' ' "$bash_source" $' --help\n'
fi
[ -x "$apply_format" ] || \
error_exit \
$'Cannot find the apply-format script.\n' \
$'I expected it here:\n' \
$' ' "$apply_format"
readonly style=$(cd "$top_dir" && git config hooks.clangFormatDiffStyle || echo file)
apply_format_opts=(
"--style=$style"
--cached
)
readonly exclusions_file="$top_dir/.clang-format-hook-exclude"
if [ -e "$exclusions_file" ]; then
while IFS= read -r line; do
if [[ "$line" && "$line" != "#"* ]]; then
apply_format_opts+=("--internal-opt-ignore-regex=$line")
fi
done < "$exclusions_file"
fi
readonly patch=$(mktemp)
trap '{ rm -f "$patch"; }' EXIT
"$apply_format" --style="$style" --cached "${apply_format_opts[@]}" > "$patch" || \
error_exit $'\nThe apply-format script failed.'
if [ "$(wc -l < "$patch")" -eq 0 ]; then
echo "The staged content is formatted correctly."
exit 0
fi
# The code is not formatted correctly.
interactive=$(cd "$top_dir" && git config --bool hooks.clangFormatDiffInteractive)
if [ "$interactive" != false ]; then
# Interactive is the default, so anything that is not false is converted to
# true, including possibly invalid values.
interactive=true
fi
readonly interactive
if [ "$interactive" = false ]; then
echo "${b}The staged content is not formatted correctly.${n}"
echo "You can fix the formatting with:"
echo " ${i}\$ ./$apply_format_relative_to_top_dir --apply-to-staged${n}"
echo
echo "You can also make this script interactive (if you use git from a terminal) with:"
echo " ${i}\$ git config hooks.clangFormatDiffInteractive true${n}"
exit 1
fi
if hash colordiff 2> /dev/null; then
colordiff < "$patch"
else
echo "${b}(Install colordiff to see this diff in color!)${n}"
echo
cat "$patch"
fi
# We don't want to suggest applying clang-format after merge resolution
if git rev-parse MERGE_HEAD >/dev/null 2>&1; then
readonly this_is_a_merge=true
else
readonly this_is_a_merge=false
fi
echo
echo "${b}The staged content is not formatted correctly.${n}"
echo "The fix shown above can be applied automatically to the commit."
echo
if $this_is_a_merge; then
echo "${b}You appear to be committing the result of a merge. It is not${n}"
echo "${b}recommended to apply the fix if it will reformat any code you${n}"
echo "${b}did not modify in your branch.${n}"
echo
readonly recommend_apply=" (not recommended for merge!)"
readonly recommend_force=""
readonly bold_apply=""
readonly bold_force="${b}"
else
readonly recommend_apply=""
readonly recommend_force=" (not recommended!)"
readonly bold_apply="${b}"
readonly bold_force=""
fi
echo "You can:"
echo " ${bold_apply}[a]: Apply the fix${recommend_apply}${n}"
echo " ${bold_force}[f]: Force and commit anyway${recommend_force}${n}"
echo " [c]: Cancel the commit"
echo " [?]: Show help"
echo
readonly tty=${PRE_COMMIT_HOOK_TTY:-/dev/tty}
while true; do
echo -n "What would you like to do? [a/f/c/?] "
read -r answer < "$tty"
case "$answer" in
[aA] )
patch -p0 < "$patch" || \
error_exit \
$'\n' \
$'Cannot apply fix to local files.\n' \
$'Have you modified the file locally after starting the commit?'
git apply -p0 --cached < "$patch" || \
error_exit \
$'\n' \
$'Cannot apply fix to git staged changes.\n' \
$'This may happen if you have some overlapping unstaged changes. To solve\n' \
$'you need to stage or reset changes manually.'
if $this_is_a_merge; then
echo
echo "Applied the fix to reformat the merge commit."
echo "You can always abort by quitting your editor with no commit message."
echo
echo -n "Press return to continue."
read -r < "$tty"
fi
;;
[fF] )
echo
if ! $this_is_a_merge; then
echo "Will commit anyway!"
echo "You can always abort by quitting your editor with no commit message."
echo
echo -n "Press return to continue."
read -r < "$tty"
fi
exit 0
;;
[cC] )
error_exit "Commit aborted as requested."
;;
\? )
echo
show_help
echo
continue
;;
* )
echo 'Invalid answer. Type "a", "f" or "c".'
echo
continue
esac
break
done
#
# Copyright 2020, Saab AB
#
# This software may be distributed and modified according to
# the terms of the MIT License.
# Note that NO WARRANTY is provided.
# See "LICENSE.MIT" for details.
#
INCLUDES = include $(BSP_DIR)
SOURCES = $(wildcard *.c *.S)
HEADERS = $(wildcard *.h $(addsuffix /*.h, $(INCLUDES)))
#CC = ccomp
#CFLAGS = -finline-asm -fno-fpu -g
CFLAGS = -march=$(ARCH) -mabi=$(ABI) -mcmodel=$(CMODEL)
CFLAGS += -g -O2
CFLAGS += $(addprefix -I, $(INCLUDES)) -nostdlib -static
CFLAGS += -T $(BSP_DIR)/memory.lds -T default.lds
.PHONY: compile
compile: $(PROGRAM_ELF)
$(PROGRAM_ELF): $(SOURCES) $(HEADERS)
$(CC) $(CFLAGS) -o $@ $(SOURCES)
$(SIZE) $@
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
OUTPUT_ARCH("riscv")
ENTRY(_start)
MEMORY
{
/* 64 KiB rom */
rom (rxai!w) : ORIGIN = rom + 0x10000, LENGTH = 0x2000
itim (wx!rai) : ORIGIN = itim, LENGTH = 0x2000
/* 4 KiB ram */
ram (wxa!ri) : ORIGIN = ram, LENGTH = 0x1000
}
SECTIONS
{
/* 1 KiB stack */
__stack_size = DEFINED(__stack_size) ? __stack_size : 0x200;
PROVIDE(__stack_size = __stack_size);
.text : {
KEEP(*(.text.init))
. = ALIGN(8);
} >rom AT>rom
.data : ALIGN(8) {
*(.data)
*(.data.*)
*(.sdata)
*(.sdata.*)
*(.rodata .rodata.*)
*(.rdata .rdata.*)
. = ALIGN(8);
} >ram AT>rom
PROVIDE(__global_pointer$ = ADDR(.data));
PROVIDE(_data_lma = LOADADDR(.data));
PROVIDE(_data = ADDR(.data));
PROVIDE(_edata = ADDR(.data) + SIZEOF(.data));
.itim : ALIGN(8) {
*(.text)
*(.text.*)
*(.itim .itim.*)
. = ALIGN(8);
} >ram AT>rom
PROVIDE(_itim_lma = LOADADDR(.itim));
PROVIDE(_itim = ADDR(.itim));
PROVIDE(_eitim = ADDR(.itim) + SIZEOF(.itim));
.bss : ALIGN(8) {
*(.bss)
*(.bss.*)
*(.sbss*)
*(COMMON)
. = ALIGN(8);
} >ram AT>ram
PROVIDE(_bss = ADDR(.bss));
PROVIDE(_ebss = ADDR(.bss) + SIZEOF(.bss));
PROVIDE(_heap = _ebss);
.stack ORIGIN(ram) + LENGTH(ram) - __stack_size : {
. += __stack_size;
} >ram AT>ram
PROVIDE(_eheap = ADDR(.stack));
PROVIDE(_sp = ADDR(.stack) + SIZEOF(.stack));
}
/**
* Copyright 2020, Saab AB
*
* This software may be distributed and modified according to
* the terms of the GNU General Public License version 2.
* Note that NO WARRANTY is provided.
* See "LICENSE.GPLv2" for details.
*/
#include "machine.h"
#include "sched.h"
#include "const.h"
#include "csr.h"
#include "kernel.h"
#include "macro.h"
#include "traps.h"
/* handler takes a caller and its argument registers a0-a7 */
typedef void (*handler_t)(zone_t* caller, uintptr_t args[8]);
/* ECALL numbers */
#define ECALL_YIELD 0
#define ECALL_WFI 1
#define ECALL_SEND 2
#define ECALL_RECV 3
#define ECALL_TRP_VECT 4
#define ECALL_IRQ_VECT 5
#define ECALL_CSRS_MIE 6
#define ECALL_CSRC_MIE 7
#define ECALL_CSRW_MTIMECMP 8
#define ECALL_CSRR_MTIME 9
#define ECALL_CSRR_MCYCLE 10
#define ECALL_CSRR_MINSTR 11
#define ECALL_CSRR_MHPMC3 12
#define ECALL_CSRR_MHPMC4 13
#define ECALL_CSRR_MISA 14
#define ECALL_CSRR_MVENDID 15
#define ECALL_CSRR_MARCHID 16
#define ECALL_CSRR_MIMPID 17
#define ECALL_CSRR_MHARTID 18
void ecall_yield(zone_t* caller, uintptr_t args[8])
{
KERNEL.deadline = read_mtime();
sched_yield();
}
static void ecall_send(zone_t* caller, uintptr_t args[8])
{
uintptr_t receiver = args[0] - 1;
args[0] = 0;
if (receiver >= N_ZONES)
return;
inbox_t* inbox = &INBOXES[receiver][caller->id - 1];
if (inbox->full)
return;
inbox->full = 1;
for (int i = 0; i < N_MSGS; ++i)
inbox->msgs[i] = args[1 + i];
args[0] = 1;
}
static void ecall_recv(zone_t* caller, uintptr_t args[8])
{
uintptr_t sender = args[0] - 1;
args[0] = 0;
if (sender >= N_ZONES)
return;
inbox_t* inbox = &INBOXES[caller->id - 1][sender];
if (!inbox->full)
return;
inbox->full = 0;
for (int i = 0; i < N_MSGS; ++i)
args[i + 1] = inbox->msgs[i];
args[0] = 1;
}
static void ecall_trp_vect(zone_t* caller, uintptr_t args[8])
{
uintptr_t code = args[0];
uintptr_t handler = args[1];
if (code >= N_TRAPS)
return;
caller->trap_handlers[code] = handler;
if (code == UMODE_SOFT_TIMER)
caller->deadline = 0;
}
static void ecall_irq_vect(zone_t* caller, uintptr_t args[8])
{
uintptr_t code = args[0];
uintptr_t handler = args[1];
if ((code >= N_INTERRUPTS) || (INTRP_HANDLERS[code].zone != caller))
return;
INTRP_HANDLERS[code].handler = handler;
if (handler) {
caller->uie |= (1 << code);
if (caller->ustatus & USTATUS_IE) {
KERNEL.mie |= (1 << code);
}
} else {
caller->uie &= ~(1 << code);
if (caller->ustatus & USTATUS_IE) {
KERNEL.mie &= ~(1 << code);
}
}
}
static void ecall_csrs_mie(zone_t* caller, uintptr_t UNUSED(args[8]))
{
caller->ustatus |= USTATUS_IE;
KERNEL.mie |= caller->uie;
}
static void ecall_csrc_mie(zone_t* caller, uintptr_t UNUSED(args[8]))
{
caller->ustatus &= ~USTATUS_IE;
KERNEL.mie &= ~caller->uie;
}
static void ecall_csrw_mtimecmp(zone_t* caller, uintptr_t args[8])
{
caller->deadline = *((uint64_t*)args);
}
static void ecall_csrr_mtime(zone_t* caller, uintptr_t args[8])
{
*((uint64_t*)args) = read_mtime();
}
static void ecall_csrr_mcycle(zone_t* caller, uintptr_t args[8])
{
CSRR_COUNTER(args[0], mcycle);
}
static void ecall_csrr_minstr(zone_t* caller, uintptr_t args[8])
{
CSRR_COUNTER(args[0], minstret);
}
static void ecall_csrr_mhpmc3(zone_t* caller, uintptr_t args[8])
{
CSRR_COUNTER(args[0], mhpmcounter3);
}
static void ecall_csrr_mhpmc4(zone_t* caller, uintptr_t args[8])
{
CSRR_COUNTER(args[0], mhpmcounter4);
}
static void ecall_csrr_misa(zone_t* caller, uintptr_t args[8])
{
CSRR64(args[0], misa);
}
static void ecall_csrr_mvendid(zone_t* caller, uintptr_t args[8])
{
CSRR64(args[0], mvendorid);
}
static void ecall_csrr_marchid(zone_t* caller, uintptr_t args[8])
{
CSRR64(args[0], marchid);
}
static void ecall_csrr_mimpid(zone_t* caller, uintptr_t args[8])
{
CSRR64(args[0], mimpid);
}
static void ecall_csrr_mhartid(zone_t* caller, uintptr_t args[8])
{
CSRR64(args[0], mhartid);
}
static const handler_t ecall_handlers[] = {
[ECALL_YIELD] = ecall_yield,
[ECALL_WFI] = ecall_yield,
[ECALL_SEND] = ecall_send,
[ECALL_RECV] = ecall_recv,
[ECALL_TRP_VECT] = ecall_trp_vect,
[ECALL_IRQ_VECT] = ecall_irq_vect,
[ECALL_CSRS_MIE] = ecall_csrs_mie,
[ECALL_CSRC_MIE] = ecall_csrc_mie,
[ECALL_CSRW_MTIMECMP] = ecall_csrw_mtimecmp,
[ECALL_CSRR_MTIME] = ecall_csrr_mtime,
[ECALL_CSRR_MCYCLE] = ecall_csrr_mcycle,
[ECALL_CSRR_MINSTR] = ecall_csrr_minstr,
[ECALL_CSRR_MHPMC3] = ecall_csrr_mhpmc3,
[ECALL_CSRR_MHPMC4] = ecall_csrr_mhpmc4,
[ECALL_CSRR_MISA] = ecall_csrr_misa,
[ECALL_CSRR_MVENDID] = ecall_csrr_mvendid,
[ECALL_CSRR_MARCHID] = ecall_csrr_marchid,
[ECALL_CSRR_MIMPID] = ecall_csrr_mimpid,
[ECALL_CSRR_MHARTID] = ecall_csrr_mhartid,
};
void handle_ecall(uintptr_t mcause, uintptr_t mtval)
{
/* ecall table */
zone_t* caller = &CURRENT;
/* always advance PC! */
caller->regs[PC] += 4;
uintptr_t ecall = caller->regs[A7];
if (ecall < ARRAY_LEN(ecall_handlers))
ecall_handlers[ecall](caller, caller->regs + A0);
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment