Skip to content

Commit

Permalink
Initial import
Browse files Browse the repository at this point in the history
  • Loading branch information
iankuan committed Aug 5, 2017
1 parent 71ed5dc commit 2f186a8
Show file tree
Hide file tree
Showing 206 changed files with 11,811 additions and 0 deletions.
15 changes: 15 additions & 0 deletions .clang-format
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
121 changes: 121 additions & 0 deletions Makefile
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
10 changes: 10 additions & 0 deletions Makefile.inc
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)
8 changes: 8 additions & 0 deletions Makefile.opt
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
146 changes: 146 additions & 0 deletions arch/v7m-entry.S
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. */
76 changes: 76 additions & 0 deletions arch/v7m-faults.c
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();
}
Loading

0 comments on commit 2f186a8

Please sign in to comment.