# Compiler flags
LDFLAGS+= -mthumb -mcpu=cortex-m3
-ASFLAGS+= -mcpu=cortex-m3 -mthumb -g
-CFLAGS+= -mcpu=cortex-m3 -mthumb -g -ffreestanding
+ASFLAGS+= -mcpu=cortex-m3 -mthumb
+CFLAGS+= -mcpu=cortex-m3 -mthumb -ffreestanding
+#CFLAGS+= -mcpu=cortex-m3 -mthumb -g -ffreestanding
# Include directory
INCLUDE+= -Iinclude
BIN = bin
ODIR = obj
-_OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o rtc.o heap.o
+_OBJ = ivt.o systick.o sysinfo.o term.o main.o clock.o rtc.o heap.o syscall.o
OBJ = $(patsubst %, $(ODIR)/%,$(_OBJ))
DDIR = obj/drivers
DRIVERS = $(patsubst %, $(DDIR)/%,$(_DRIVERS))
LDIR = obj/lib
-_LIBS = string.o stdio.o regfunc.o pool.o tinyprintf.o
+_LIBS = string.o stdio.o regfunc.o pool.o tinyprintf.o syscall.o
LIBS = $(patsubst %, $(LDIR)/%,$(_LIBS))
$(DDIR)/%.o: drivers/%.c
# Run in Qemu; note this is a patched version for stm32-f103c8
run:
- /usr/local/bin/qemu-system-arm -serial stdio -M stm32-f103c8 -kernel $(BIN)/kernel.bin
+ /usr/local/bin/qemu-system-arm -monitor stdio -serial stdio -M stm32-f103c8 -kernel $(BIN)/kernel.bin
# Examine all sections
examine-all:
--- /dev/null
+/* syscall.h */
+extern void theos_test();
extern void kfree(void * s, void * p);
extern void kheap_info(void * s);
+/* SYSCALL.C */
+extern void syscall_init();
+
/* TERM.C */
extern void terminal();
"BUS FAULT",
"USAGE FAULT",
"RESERVED",
+ "RESERVED",
+ "RESERVED",
+ "RESERVED",
"SVC",
"DEBUG MONITOR",
"RESERVED",
/* Dummy interrupt: comment out the comment to use a naked
* function */
-__attribute__ ((interrupt))
-void * dummy_isr( struct interrupt_frame * frame ) {
+struct interrupt_frame * frame;
+
+//__attribute__ ((interrupt))
+void * dummy_isr( struct interrupt_frame * f ) {
+
+ //uint32_t link_register = 0;
+ //asm ("mov %0, #33" : "=r" (lp));
+
+ /* Check Link Register:
+ * If you ever need to debug these: here are the most common
+ * values
+ * 0xFFFFFFF1: return to handler mode (nested interrupts
+ * 0xFFFFFFF9: return to thread mode using main stack
+ * 0xFFFFFFFD: return to thread mode using process stack */
+ // asm ("mov %0, lr" : "=r" (link_register));
+ // printf("%x\n", link_register);
+ // for(;;);
+
+// asm volatile ("push {r0-r12}");
+// int * stack;
+// asm volatile ("tst lr, #4" "\n\t"
+// "ite eq" "\n\t"
+// "mrseq %0, msp" "\n\t"
+// "mrsne r0, psp" : "=r" (stack));
+//
+// printf("STACK: %x, %x, %x, %x, %x", stack[32], stack[28], stack[24], stack[20], stack[16]);
+
+// asm volatile ("CPSID f");
+
+// uint32_t tmp = args[0];
+// uint32_t tmp2 = args[1];
+// printf("%x, %x\n", tmp, tmp2);
+// uint32_t tmp3 = args[2];
+// uint32_t tmp4 = args[3];
+// printf("%x, %x\n", tmp3, tmp4);
+
+ struct interrupt_frame * frame = (struct interrupt_frame * )kalloc(get_kheap());
+ memcpy(frame, f, sizeof(struct interrupt_frame));
uint8_t nr = *SCB_VTOR_ST & 0xFF;
printf("EXCEPTION: %s\n", exception_message(nr));
printf("PC:%p\n",frame->pc);
printf("PSR:%p\n",frame->psr);
- for(;;);
+ for(;;);
}
/* Initialize interrupt vector */
--- /dev/null
+
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/9/21 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ * System calls for user functions
+ *
+ */
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <lib/syscall.h>
+
+
+//__attribute__ ((naked))
+static int theos_syscall(int SYSCALL_N, int SYSCALL_N2) {
+
+ asm volatile ("svc 11");
+
+ return 0;
+}
+
+//__attribute__ ((naked))
+void theos_test(int dummy, int dummy2) {
+
+ theos_syscall(0xB1, 0xB2);
+}
+
+/* void theos_cputs(const char * str, size_t len) {
+
+ //syscall(#, 0, 0, 0 ..);
+ theos_syscall(22, 44);
+} */
#include <drivers/st7735s.h>
+#include <lib/syscall.h>
+
+int test3(int i, int j) {
+
+ volatile uint32_t * sp = get_msp();
+
+ /* asm volatile (
+ "tst lr, #4" "\n\t"
+ "ite eq" "\n\t"
+ "mrseq %0, msp" "\n\t"
+ "mrsne r0, psp" : "=r" (sp) ); */
+
+ for (int i = 0; (sp + i) < 0x20010000; i++) {
+ printf("ADDRESS: %p, VALUE: %x\n", (sp + i), *(sp + i));
+ }
+
+ for(;;);
+ return 0xCC;
+
+}
+int test2(int i, int j) {
+
+ int x = i * j;
+ test3(0x3A, 0x3B);
+
+
+}
+int test(int i, int j) {
+
+ test2(0x2A, 0x2B);
+
+ return 0xAA;
+}
+
void main()
{
init_printf(NULL, putc);
/* Heap init */
- kheap_init();
+ //kheap_init();
//printf("%p\n", get_kheap());
/* Display some basic info at startup */
led_init();
/* Real time clock */
- rtc_init();
+ //rtc_init();
+
+// printf("press any key to start\n");
+// asm volatile ("wfi");
+ syscall_init();
+ theos_test(0xA1, 0xA2);
/* Eeprom Driver
eeprom_at24c_init();
.text
.global _start
.global reset, nmi, hardfault
+ .global _svc_handler
.code 16
.syntax unified
_start:
/* These are consequently the nmi and hardfault vector handlers
before booting and entering main, these can actually be called
(machine somehow has a failure). That's why they are included here.
- Later the interrupt vector
- will be relocated to SRAM and the will be copied / modified. */
+ Later the interrupt vector will be relocated to SRAM and modified. */
nmi:
b nmi
-hardfault:
- b hardfault
-
+hardfault:
+ mov r5, 9
+ b hardfault2
+
+hardfault2:
+ b hardfault2
+
.end
--- /dev/null
+/* (CC-BY-NC-SA) ROBIN KRENS - ROBIN @ ROBINKRENS.NL
+ *
+ * $LOG$
+ * 2019/9/20 - ROBIN KRENS
+ * Initial version
+ *
+ * $DESCRIPTION$
+ *
+ * |----------------------------|
+ * | SYSTEM CALL | # |
+ * |--------------------|-------|
+ * | THEOS_getenv | |
+ * | THEOS_killenv | |
+ * | THEOS_setenv | |
+ * | THEOS_newenv | |
+ * | THEOS_cputs | |
+ * | THEOS_omnigod | |
+ * | THEOS_brk | |
+ * | THEOS_time | |
+ * | THEOS_magic | |
+ * |----------------------------|
+ *
+ * TODO: include in header enum
+ * */
+
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+
+#include <sys/robsys.h>
+#include <sys/mmap.h>
+
+#include <lib/stdio.h>
+#include <lib/string.h>
+#include <lib/regfunc.h>
+#include <lib/tinyprintf.h>
+
+
+/* the function gets called for
+ * */
+__attribute__ ((naked))
+void * __svc_handler__(int x) {
+
+ uint8_t svc_nr;
+
+ asm volatile (
+ "tst lr, #4" "\n\t"
+ "ite eq" "\n\t"
+ "mrseq r0, msp" "\n\t"
+ "mrsne r0, psp" "\n\t"
+ "ldr r0, [r0, #24]" "\n\t"
+ "ldrb %0, [r0, #-2]" : "=r" (svc_nr) );
+
+ printf("SYSTEM CALL NR: %d", svc_nr);
+
+ for(;;);
+
+ volatile uint32_t * sp;
+
+ asm volatile (
+ "tst lr, #4" "\n\t"
+ "ite eq" "\n\t"
+ "mrseq %0, msp" "\n\t"
+ "mrsne r0, psp" : "=r" (sp) );
+
+
+ for (int i = 0; (sp + i) < 0x20010000; i++) {
+ printf("ADDRESS: %p, VALUE: %x\n", (sp + i), *(sp + i));
+ }
+
+ for (;;);
+ //asm ("mov %0, pc" : "=r" (link_register));
+ //printf("%x\n", link_register);
+
+ volatile uint32_t * svc_number = (uint32_t *) 0x20022222;
+ *svc_number = sp[-6];
+ // = sp[6];
+ //uint8_t tmp = link_register[-2];
+ printf("SVC nr: %x", *svc_number);
+ //printf("%d, %d, %d, %d, %d, %d\n", msp[6], msp[0], msp[1], msp[2], msp[3], msp[4]);
+
+ for (;;);
+ //return NULL;
+ return 0;
+
+}
+
+void syscall(unsigned int * args) {
+
+ uint32_t svc_number = 99;
+ printf("SYSCALL NR: %x", svc_number);
+
+ for(;;);
+ /* switch(SYSCALL_NO) {
+ case THEOS_cputs:
+ kernel_cputs(a1, a2);
+ break;
+ default:
+ for (;;);
+ } */
+
+}
+
+void syscall_init() {
+
+
+ /* SVC is located at position 11 in the interrupt vector table */
+// extern void * _syscall;
+ extern void * hardfault;
+
+ ivt_set_gate(11, __svc_handler__, 0);
+
+
+}
+
+static void kernel_cputs(char * s, size_t l) {
+
+ // TODO
+}
+
+
+void kernel_omnigod() {
+
+ /* */
+
+}
+
+
+