]> rtime.felk.cvut.cz Git - l4.git/blob - kernel/fiasco/src/kern/arm/sys_call_page-arm.cpp
1d1d71513f52836d8ef4b8714cd65eef0bca8669
[l4.git] / kernel / fiasco / src / kern / arm / sys_call_page-arm.cpp
1 INTERFACE:
2
3 #include "types.h"
4
5 //----------------------------------------------------------------------------
6 IMPLEMENTATION[arm && !armv6plus]:
7
8 PRIVATE static inline NOEXPORT NEEDS["types.h"]
9 void
10 Sys_call_page::set_utcb_get_code(Unsigned32 *sys_calls)
11 {
12   unsigned offset = 0;
13   sys_calls[offset++] = 0xe3e00a02; // mvn r0, #8192
14   sys_calls[offset++] = 0xe5100fff; // ldr r0, [r0, -#4095]
15   sys_calls[offset++] = 0xe1a0f00e; // mov pc, lr
16
17   // set TLS REG
18   offset = 0x20;
19   sys_calls[offset++] = 0xe1a0f00e; // mov pc, lr
20 }
21
22 //----------------------------------------------------------------------------
23 IMPLEMENTATION[arm && armv6plus]:
24
25 PRIVATE static inline NOEXPORT NEEDS["types.h"]
26 void
27 Sys_call_page::set_utcb_get_code(Unsigned32 *sys_calls)
28 {
29   unsigned offset = 0;
30
31   // sys_calls[0] = 0xee1d0f70; // mrc 15, 0, r0, cr13, cr0, {3}
32   sys_calls[offset++] = 0xee1d0f50; // mrc 15, 0, r0, cr13, cr0, {2}
33   sys_calls[offset++] = 0xe1a0f00e; // mov pc, lr
34
35   // set TLS REG
36   offset = 0x20;
37   sys_calls[offset++] = 0xe92d4010; // push    {r4, lr}
38   sys_calls[offset++] = 0xee1d4f50; // mrc     15, 0, r4, cr13, cr0, {2}
39   sys_calls[offset++] = 0xe5840004; // str     r0, [r4, #4]
40   sys_calls[offset++] = 0xe3a02010; // mov     r2, #0x10 -> set tls opcode
41   sys_calls[offset++] = 0xe5842000; // str     r2, [r4]
42   sys_calls[offset++] = 0xe3a03000; // mov     r3, #0
43   sys_calls[offset++] = 0xe30f2803; // movw    r2, #0xf803
44   sys_calls[offset++] = 0xe3a00002; // mov     r0, #2
45   sys_calls[offset++] = 0xe34f2fff; // movt    r2, #0xffff
46   sys_calls[offset++] = 0xe34f0ff4; // movt    r0, #0xfff4
47   sys_calls[offset++] = 0xe1a0e00f; // mov     lr, pc
48   sys_calls[offset++] = 0xe3e0f00b; // mvn     pc, #11
49   sys_calls[offset++] = 0xe8bd8010; // pop     {r4, pc}
50 }
51
52 //----------------------------------------------------------------------------
53 IMPLEMENTATION:
54
55 #include <cstring>
56 #include "kernel_task.h"
57 #include "mem_layout.h"
58 #include "vmem_alloc.h"
59 #include "panic.h"
60
61 IMPLEMENT static
62 void
63 Sys_call_page::init()
64 {
65   Unsigned32 *sys_calls = (Unsigned32*)Kmem_alloc::allocator()->unaligned_alloc(Config::PAGE_SIZE);
66   if (!sys_calls)
67     panic("FIASCO: can't allocate system-call page.\n");
68
69   for (unsigned i = 0; i < Config::PAGE_SIZE / sizeof(Unsigned32); ++i)
70     sys_calls[i] = 0xef000000; // svc
71
72   set_utcb_get_code(sys_calls + (0xf00 / sizeof(Unsigned32)));
73   Mem_unit::flush_cache();
74
75   Kernel_task::map_syscall_page(sys_calls);
76 }