aboutsummaryrefslogtreecommitdiff
path: root/src/kern/priv.c
blob: 085de859d69d9deb2d84946b39de969240593f6d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
#include "kern/priv.h"

#include "arch.h"
#include "kern/log.h"

void handle_svc_call(uint32_t svc_number)
{
  klogf("Handle SVC: %p\n", svc_number);
  for (;;)
    ;
}

asm("	.align	2\n"
    "	.global	on_svc\n"
    "	.syntax unified\n"
    "	.fpu softvfp\n"
    "	.type	on_svc, %function\n"
    "on_svc:\n"
    "	tst   lr,#4\n"
    " ite   eq\n"
    "	moveq r12,sp\n"
    "	mrsne r12,psp\n"
    "	ldr   r12, [r12, #24]\n"
    "	ldrh  r12, [r12, #-2]\n"
    "	bics  r12, r12, #0xff00\n"
    "	push  {r4, lr}\n"
    "	mov   r0 , r12\n"
    "	bl    handle_svc_call\n"
    "	pop   {r4, lr}\n"
    "	tst   lr, #4\n"
    " ite   eq\n"
    "	moveq r12,sp\n"
    "	mrsne r12,psp\n"
    "	stm   r12,{r0-r3}\n"
    "	bx    lr\n");

// void on_svc()  // ISR handler. Override from weak symbol.
// {
// asm volatile(
//     "push {r0-r12, lr}\n\t"
//     "ldr  r0, [lr, #-4]\n\t"
//     "bic  r0, r0, #0xff000000\n\t"
//     );

// TST     LR,#4                   ; Called from Handler Mode?
// MRSNE   R12,PSP                 ; Yes, use PSP
// MOVEQ   R12,SP                  ; No, use MSP
// LDR     R12,[R12,#24]           ; Read Saved PC from Stack
// LDRH    R12,[R12,#-2]           ; Load Halfword
// BICS    R12,R12,#0xFF00         ; Extract SVC Number
// uint32_t reg;
// asm volatile(
//     "mov  r12, sp\n\t"
//     "ldr  r12, [r12,#24]\n\t"
//     // "ldrh r12,[r12, #-2]\n\t"
//     // "bics r12, r12, #0xff00\n\t"
//     "mov  %0, r12\n\t": "=r"(reg));

//   uint32_t base[0];
//   uint32_t reg;
//
//
//   asm volatile("mov  %0, sp\n\t" : "=r"(reg));
//   uint32_t* at = (uint32_t*) (reg + 44); /* Does GCC set up 5 stack frame
//   words? */
//
//   klogf("Stack pointer: %p\n", reg);
//   klogf("Stack pointer +44: %p\n", (reg + 44));
//   klogf("At_: %p: %p\n\n", 0x80009f6, *(uint32_t*)0x80009f6);
//   klogf("At: %p: %p\n\n", at, *at);
//
//
//   int i = 0;
//   for (; i < 20 && &base[i] != (void*)STACK_TOP; ++ i) {
//     kerr_logf(" (%p) %p\n", &base[i], base[i]);
//   }
//
//   // klogf("TEST %p\n", reg);
//
//   for(;;);

// register int svc_number asm ("r0");

// klogf("SVC #: %p\n", svc_number);
// }

void set_control_register(uint32_t reg)
{
  asm volatile("msr control, %0" : "=r"(reg) :);
}

uint32_t get_control_register()
{
  uint32_t control;
  asm volatile("mrs %0, control" : "=r"(control) :);
  return control;
}

void enter_user_mode()
{
  asm volatile(
      "mov r0, #1\n\t"
      "msr control, r0\n\t");
}