forked from PikoRT/pikoRT
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
206 changed files
with
11,811 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
BasedOnStyle: Chromium | ||
Language: Cpp | ||
MaxEmptyLinesToKeep: 3 | ||
IndentCaseLabels: false | ||
AllowShortIfStatementsOnASingleLine: false | ||
AllowShortCaseLabelsOnASingleLine: false | ||
AllowShortLoopsOnASingleLine: false | ||
DerivePointerAlignment: false | ||
PointerAlignment: Right | ||
SpaceAfterCStyleCast: true | ||
TabWidth: 4 | ||
UseTab: Never | ||
IndentWidth: 4 | ||
BreakBeforeBraces: Linux | ||
AccessModifierOffset: -4 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
include Makefile.opt | ||
include Makefile.inc | ||
|
||
NAME = piko | ||
|
||
# select QEMU when the target is unspecified | ||
TARGET ?= stm32f429 | ||
CMSIS = ../cmsis | ||
|
||
# The platform Makefile contains hw details and flags | ||
include target/$(TARGET)/Makefile | ||
|
||
# warning: return type of 'main' is not 'int' [-Wmain] | ||
CFLAGS += -Iinclude -Iinclude/libc -I. -I$(CMSIS)/arm -I$(CMSIS)/$(TARGET) -I$(CMSIS)/$(TARGET)/hal \ | ||
-Iinclude/kernel -D_POSIX_THREADS=1 -D_POSIX_TIMERS=1 -D_POSIX_REALTIME_SIGNALS=1 \ | ||
-Wno-main -DCONFIG_KERNEL_STACK_CHECKING -fdiagnostics-color \ | ||
-ffunction-sections -fdata-sections -Os -ggdb | ||
|
||
LDFLAGS += -nostartfiles -specs=nano.specs \ | ||
-Wl,-Map=$(NAME).map -Wl,-Tpiko.lds -Wl,--gc-sections | ||
|
||
# arch-specific | ||
SSRC += arch/v7m-head.S arch/v7m-entry.S arch/v7m-svcall.S | ||
CSRC += arch/v7m-faults.c | ||
|
||
LIBPIKO_CSRC = $(wildcard libc/*.c) | ||
LIBPIKO_SSRC = $(wildcard libc/*.S) $(wildcard libc/piko/*.S) | ||
|
||
SSRC += $(LIBPIKO_SSRC) | ||
|
||
CSRC += kernel/syscall.c | ||
CSRC += $(wildcard kernel/*.c) \ | ||
$(wildcard kernel/fs/*.c) \ | ||
$(wildcard kernel/mm/*.c) \ | ||
$(wildcard drivers/char/*.c) \ | ||
$(wildcard drivers/mtd/*.c) \ | ||
$(wildcard drivers/timer/timercore.c) \ | ||
$(wildcard drivers/serial/serial*.c) \ | ||
$(wildcard user/*.c) \ | ||
libc/piko/stubs.c \ | ||
libc/piko/mman.c \ | ||
$(LIBPIKO_CSRC) \ | ||
|
||
OBJS += $(SSRC:.S=.o) $(CSRC:.c=.o) | ||
OBJS := $(sort $(OBJS)) | ||
|
||
.PHONY: all check clean distclean | ||
|
||
all: $(CMSIS)/$(TARGET) $(NAME).lds $(NAME).hex $(NAME).bin | ||
|
||
prebuild: $(CMSIS)/$(TARGET) | ||
|
||
$(NAME).elf: $(OBJS) kernel/fs/version.o | ||
$(VECHO) "LD\t$@" | ||
$(Q)$(CC) $(LDFLAGS) -o $@ $^ | ||
|
||
%.o: %.c | ||
$(VECHO) "CC\t$@" | ||
$(Q)$(CC) -o $@ $(CFLAGS) -c -W -Wall -std=c11 -D__KERNEL__ $< | ||
|
||
%.o: %.S | ||
$(VECHO) "AS\t$@" | ||
$(Q)$(CC) -o $@ $(CFLAGS) -c $< | ||
|
||
%.lds: %.lds.S | ||
$(VECHO) "HOSTCC\t$@" | ||
$(Q)$(HOSTCC) -E -P -Iinclude -DROMSZ=$(ROMSZ) -DRAMSZ=$(RAMSZ) -o $@ $< | ||
|
||
include/cmsis/arm/core_cm4.h: | ||
git submodule init | ||
git submodule update | ||
|
||
kernel/syscall.c: include/kernel/syscalls.h | ||
$(VECHO) "GEN\t$@" | ||
$(Q)python scripts/gen-syscalls.py --source > $@ | ||
|
||
include/kernel/syscalls.h: | ||
$(VECHO) "GEN\t$@" | ||
$(Q)python scripts/gen-syscalls.py --header > $@ | ||
|
||
kernel/fs/version: | ||
$(VECHO) "GEN\t$@" | ||
$(Q)python3 scripts/gen-proc-version.py --cc-version \ | ||
--user $(shell whoami) --host $(shell hostname) \ | ||
-a $(ARCH) -c $(CPU) -n 'Piko' > $@ | ||
|
||
kernel/fs/version.o: kernel/fs/version | ||
$(VECHO) "OBJCOPY\t$@" | ||
$(Q)$(OBJCOPY) -I binary -O elf32-littlearm -B arm \ | ||
--rename-section .data=.rodata \ | ||
--redefine-sym _binary_$(subst /,_,$<)_start=_version_ptr \ | ||
--redefine-sym _binary_$(subst /,_,$<)_size=_version_len \ | ||
$< $@ | ||
|
||
%.hex: %.elf | ||
$(VECHO) "OBJCOPY\t$@" | ||
$(Q)$(OBJCOPY) -O ihex $< $@ | ||
|
||
%.bin: %.elf | ||
$(VECHO) "OBJCOPY\t$@" | ||
$(Q)$(OBJCOPY) -Obinary $< $@ | ||
|
||
check: | ||
python3 tests/runner.py | ||
|
||
clean: | ||
find . -name "*.o" -type f -delete | ||
find $(CMSIS) -name "*.o" -type f -delete | ||
rm -f $(NAME).map $(NAME).lds | ||
rm -f $(NAME).elf $(NAME).hex | ||
rm -f $(NAME).bin | ||
|
||
distclean: clean | ||
rm -f kernel/syscall.c include/kernel/syscalls.h kernel/fs/version | ||
rm -rf $(CMSIS) | ||
|
||
astyle: | ||
astyle --style=linux --indent=tab --indent-switches --suffix=none --recursive *.c *.h | ||
|
||
# platform Makefile.rules contains flashing and running rules | ||
include target/$(TARGET)/Makefile.rules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
CROSS = arm-none-eabi- | ||
CC = $(CROSS)gcc | ||
AS = $(CROSS)as | ||
AR = $(CROSS)ar | ||
OBJCOPY = $(CROSS)objcopy | ||
GDB = $(CROSS)gdb | ||
HOSTCC = gcc | ||
|
||
CFLAGS += -mthumb -mcpu=$(CPU) | ||
LDFLAGS += -mthumb -march=$(ARCH) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# Control the build verbosity | ||
ifeq ("$(VERBOSE)","1") | ||
Q := | ||
VECHO = @true | ||
else | ||
Q := @ | ||
VECHO = @echo | ||
endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
#include <kernel/linkage.h> | ||
|
||
.syntax unified | ||
.thumb | ||
|
||
@ do the thread-context switch | ||
@ | ||
@ r0: struct thread_info *next | ||
@ r1: struct thread_info *prev (i.e. the current thread) | ||
@ (r1), r2, r3, r12: scratch registers | ||
ENTRY(switch_to) | ||
/* save previous thread context */ | ||
push {r4-r12, lr} | ||
mov r2, sp | ||
mrs r3, psp | ||
stm r1!, {r2, r3} | ||
|
||
ENTRY(thread_restore) | ||
/* restore next task context */ | ||
ldm r0!, {r1-r3} | ||
mov sp, r1 | ||
msr psp, r2 | ||
msr control, r3 @ write to SPSEL is ignored in Handler_Mode | ||
pop {r4-r12, pc} | ||
ENDPROC(thread_restore) | ||
ENDPROC(switch_to) | ||
|
||
.macro emulate_iret | ||
ldrd r0, r1, [sp, #24] /* r0 = ret_addr, r1 = xpsr */ | ||
orr r0, #1 | ||
str r0, [sp, #24] | ||
msr apsr_nzcvq, r1 /* restore flags */ | ||
pop {r0-r3, r12, lr} | ||
ldr pc, [sp], #8 /* return into user thread */ | ||
.endm | ||
|
||
ENTRY(return_from_sigaction) | ||
add sp, #12 /* reclaim siginfo_t storage */ | ||
emulate_iret | ||
END(return_from_sigaction) | ||
|
||
ENTRY(return_from_sighandler) | ||
emulate_iret | ||
END(return_from_sighandler) | ||
|
||
.set MC_SP, 0 | ||
.set MC_LR, 4 | ||
.set MC_GPRS, 8 | ||
.set MC_PC, 15*4 | ||
.set UC_MCONTEXT, 16 | ||
.set UC_LINK, 0 | ||
|
||
/* Swap context to a clean context (created from makecontext()): | ||
* - save the non-scratch registers | ||
* - just restore scratch registers (for arguments to entry function) | ||
* | ||
* Swap to a dirty context (inited with getcontext, or return to a | ||
* swapped context): | ||
* - save the non-scratch registers | ||
* - restore all registers | ||
*/ | ||
|
||
ENTRY(swapcontext) | ||
/* save to oucp */ | ||
add r0, #UC_MCONTEXT | ||
str sp, [r0, #MC_SP] | ||
str lr, [r0, #MC_LR] | ||
add r0, #MC_GPRS | ||
stm r0, {r0-r12, lr} | ||
|
||
/* retore from ucp */ | ||
add r1, #UC_MCONTEXT | ||
ldr sp, [r1, #MC_SP] | ||
ldr lr, [r1, #MC_LR] | ||
add r1, #MC_GPRS | ||
ldm r1, {r0-r12, pc} | ||
ENDPROC(swapcontext) | ||
|
||
ENTRY(return_from_makecontext) | ||
/* retrieve the struct& from the top of the stack */ | ||
ldr r0, [sp] | ||
|
||
/* get the machine struct for the linked context */ | ||
ldr r0, [r0, #UC_LINK] | ||
add r0, #UC_MCONTEXT | ||
|
||
/* restore the link context */ | ||
ldr sp, [r0, #MC_SP] | ||
ldr lr, [r0, #MC_LR] | ||
add r0, #MC_GPRS | ||
//FIXME: return code - the r0 value that is restored from the stack should be 0 | ||
ldm r0, {r0-r12, pc} | ||
ENDPROC(return_from_makecontext) | ||
|
||
.macro fault_handler f | ||
push {r4-r11} @ save non-scratch registers at time of fault | ||
mov r0, sp | ||
mov r2, lr @ lr contains EXC_RETURN, fault was taken in thread or interrupt? | ||
|
||
@ We don't handle faults taken in interrupt handler at the moment. | ||
@ Hence the scratch registers auto pushed to the stack by the CPU | ||
@ on interrupt-entry have been pushed to PSP (MSP is only used by | ||
@ interrupts handler). | ||
mrs r1, psp | ||
|
||
b \f | ||
.endm /* fault_handler */ | ||
|
||
ENTRY(hardf) | ||
fault_handler hardfault | ||
ENDPROC(hardf) | ||
|
||
ENTRY(memf) | ||
fault_handler memmanage | ||
ENDPROC(memf) | ||
|
||
ENTRY(busf) | ||
fault_handler busfault | ||
ENDPROC(busf) | ||
|
||
ENTRY(usgf) | ||
fault_handler usagefault | ||
ENDPROC(usgf) | ||
|
||
ENTRY(__do_idle) | ||
wfi | ||
bx lr | ||
ENDPROC(__do_idle) | ||
|
||
/* void v7m_semihost_exit(int status); */ | ||
ENTRY(v7m_semihost_exit) | ||
tst r0, r0 | ||
ite eq | ||
ldreq r1, =0x20026 /* [a] */ | ||
movne r1, #0 | ||
mov r0, #0x18 /* [b] */ | ||
bkpt #0xab | ||
0: b 0b | ||
ENDPROC(v7m_semihost_exit) | ||
|
||
/* [a] https://lists.nongnu.org/archive/html/qemu-devel/2014-12/msg01575.html | ||
* ADP_Stopped_ApplicationExit is used for exit(0), anything else is | ||
* implemented as exit(1). */ | ||
|
||
/* [b] http://git.qemu.org/?p=qemu.git;a=blob_plain;f=target-arm/arm-semi.c;hb=HEAD | ||
* List of supported semihosting calls in Qemu. */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <kernel/faults.h> | ||
#include <kernel/thread.h> | ||
|
||
#include "kernel.h" | ||
|
||
#define UFSR_DIVBYZERO (1 << 9) | ||
#define UFSR_UNALIGNED (1 << 8) | ||
#define UFSR_NOCP (1 << 3) | ||
#define UFSR_INVPC (1 << 2) | ||
#define UFSR_INVSTATE (1 << 1) | ||
#define UFSR_UNDEFINSTR 1 | ||
|
||
void dump_frame(struct kernel_context_regs *noscratch, | ||
struct thread_context_regs *scratch, | ||
u32 exc_return) | ||
{ | ||
printk(" r0: %08x r1: %08x r2: %08x r3: %08x\n", | ||
scratch->r0_r3__r12[0], scratch->r0_r3__r12[1], | ||
scratch->r0_r3__r12[2], scratch->r0_r3__r12[3]); | ||
printk(" r4: %08x r5: %08x r6: %08x r7: %08x\n", | ||
noscratch->r4_r12[0], noscratch->r4_r12[1], noscratch->r4_r12[2], | ||
noscratch->r4_r12[3]); | ||
printk(" r8: %08x r9: %08x r10: %08x r11: %08x\n", | ||
noscratch->r4_r12[4], noscratch->r4_r12[5], noscratch->r4_r12[6], | ||
noscratch->r4_r12[7]); | ||
printk("r12: %08x sp: %08x lr: %08x pc: %08x\n", | ||
scratch->r0_r3__r12[4], (u32) scratch, scratch->lr, | ||
scratch->ret_addr); | ||
printk("\nEXC_RETURN: %08x\n", exc_return); | ||
} | ||
|
||
void usagefault(struct kernel_context_regs *noscratch, | ||
struct thread_context_regs *scratch, | ||
u32 exc_return) | ||
{ | ||
u32 ufsr = (*((volatile u32 *) 0xe000ed28)) >> 16; | ||
const char *cause = NULL; | ||
|
||
fault_enter("UsageFault"); | ||
dump_frame(noscratch, scratch, exc_return); | ||
if (ufsr & UFSR_DIVBYZERO) | ||
cause = "DIVBYZERO"; | ||
else if (ufsr & UFSR_UNALIGNED) | ||
cause = "UNALIGNED"; | ||
else if (ufsr & UFSR_NOCP) | ||
cause = "NOCP"; | ||
else if (ufsr & UFSR_INVPC) | ||
cause = "INVPC"; | ||
else if (ufsr & UFSR_INVSTATE) | ||
cause = "INVSTATE"; | ||
else if (ufsr & UFSR_UNDEFINSTR) | ||
cause = "UNDEFINSTR"; | ||
if (cause) | ||
printk(" ufsr: %08x <%s>\n", ufsr, cause); | ||
else | ||
printk(" ufsr: %08x\n", ufsr); | ||
fault_exit(); | ||
} | ||
|
||
void busfault(struct kernel_context_regs *noscratch, | ||
struct thread_context_regs *scratch, | ||
u32 exc_return) | ||
{ | ||
fault_enter("BusFault"); | ||
dump_frame(noscratch, scratch, exc_return); | ||
fault_exit(); | ||
} | ||
|
||
void memmanage(struct kernel_context_regs *noscratch, | ||
struct thread_context_regs *scratch, | ||
u32 exc_return) | ||
{ | ||
fault_enter("MemManage"); | ||
dump_frame(noscratch, scratch, exc_return); | ||
fault_exit(); | ||
} |
Oops, something went wrong.