SYSCALL naked assembly working
authorRobin Krens <robin@robinkrens.nl>
Tue, 22 Oct 2019 19:04:20 +0000 (21:04 +0200)
committerRobin Krens <robin@robinkrens.nl>
Tue, 22 Oct 2019 19:04:20 +0000 (21:04 +0200)
Makefile
include/lib/syscall.h [new file with mode: 0644]
include/sys/robsys.h
ivt.c
lib/syscall.c [new file with mode: 0644]
main.c
start.asm
syscall.c [new file with mode: 0644]

index d6a161a..6d3ec19 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -11,8 +11,9 @@ MKIMG=arm-none-eabi-objcopy
 
 # 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 
@@ -20,7 +21,7 @@ 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
@@ -28,7 +29,7 @@ _DRIVERS = uart.o tm1637.o led.o tsensor.o at24c.o mk450_joystick.o st7735s.o
 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
@@ -57,7 +58,7 @@ kernel: $(OBJ) $(DRIVERS) $(LIBS)
 
 # 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:
diff --git a/include/lib/syscall.h b/include/lib/syscall.h
new file mode 100644 (file)
index 0000000..ddf6882
--- /dev/null
@@ -0,0 +1,2 @@
+/* syscall.h */
+extern void theos_test();
index 9d1db41..705bd8c 100644 (file)
@@ -37,6 +37,9 @@ extern void * kalloc(void * s);
 extern void kfree(void * s, void * p);
 extern void kheap_info(void * s);
 
+/* SYSCALL.C */
+extern void syscall_init();
+
 /* TERM.C */
 extern void terminal();
 
diff --git a/ivt.c b/ivt.c
index a271487..0e2d1f2 100644 (file)
--- a/ivt.c
+++ b/ivt.c
@@ -76,6 +76,9 @@ char * messages[] = {
     "BUS FAULT",
     "USAGE FAULT",
     "RESERVED",
+    "RESERVED",
+    "RESERVED",
+    "RESERVED",
     "SVC",
     "DEBUG MONITOR",
     "RESERVED",
@@ -109,8 +112,44 @@ void ivt_set_gate(unsigned char num, void * isr(), short pri) {
 /* 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));
@@ -124,7 +163,7 @@ void * dummy_isr( struct interrupt_frame * frame ) {
        printf("PC:%p\n",frame->pc);
        printf("PSR:%p\n",frame->psr);
        
-       for(;;);
+       for(;;); 
 }
 
 /* Initialize interrupt vector  */
diff --git a/lib/syscall.c b/lib/syscall.c
new file mode 100644 (file)
index 0000000..106c235
--- /dev/null
@@ -0,0 +1,38 @@
+
+/* (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);
+} */
diff --git a/main.c b/main.c
index 26a7305..e87131a 100644 (file)
--- a/main.c
+++ b/main.c
 #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()
 {
 
@@ -56,7 +90,7 @@ void main()
        init_printf(NULL, putc);
 
        /* Heap init */
-       kheap_init();
+       //kheap_init();
        //printf("%p\n", get_kheap());
        
        /* Display some basic info at startup */
@@ -66,8 +100,13 @@ void main()
        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();
index f2c16bc..e6d08c6 100644 (file)
--- a/start.asm
+++ b/start.asm
@@ -13,6 +13,7 @@
        .text
        .global _start
        .global reset, nmi, hardfault
+       .global _svc_handler
        .code 16
        .syntax unified
 _start:
@@ -28,14 +29,17 @@ reset:
 /* 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
 
diff --git a/syscall.c b/syscall.c
new file mode 100644 (file)
index 0000000..f6e1cba
--- /dev/null
+++ b/syscall.c
@@ -0,0 +1,130 @@
+/* (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() {
+
+       /* */
+
+}
+
+
+