xref: /nrf52832-nimble/rt-thread/components/vmm/vmm.c (revision 104654410c56c573564690304ae786df310c91fc)
1 /*
2  *  VMM startup file.
3  *
4  * COPYRIGHT (C) 2013-2014, Real-Thread Information Technology Ltd
5  * All rights reserved
6  *
7  * SPDX-License-Identifier: Apache-2.0
8  *
9  * Change Logs:
10  * Date           Author       Notes
11  * 2013-06-15     Bernard      the first verion
12  */
13 
14 #include <rthw.h>
15 #include <rtthread.h>
16 
17 #include "board.h"
18 
19 #include "vmm.h"
20 #include "vmm_context.h"
21 
22 extern void rt_hw_interrupt_init(void);
23 extern void rt_application_init(void);
24 
25 void vmm_entry(struct vmm_entry_param* param) SECTION(".vmm_init");
26 
27 #ifdef RT_USING_LOGTRACE
28 #include <log_trace.h>
29 static struct log_trace_session _lgs = {
30     .id  = {.name = "vmm"},
31     .lvl = LOG_TRACE_LEVEL_VERBOSE,
32 };
33 #endif
34 
35 struct rt_thread vmm_thread SECTION(".bss.share.vmm");
36 extern rt_uint8_t vmm_stack_start;
37 extern rt_uint8_t vmm_stack_end;
38 
vmm_thread_init(struct rt_thread * thread,const char * name)39 void vmm_thread_init(struct rt_thread *thread, const char *name)
40 {
41     extern struct rt_thread *rt_current_thread;
42 
43     rt_thread_init(thread, name, RT_NULL, RT_NULL,
44                    &vmm_stack_start, &vmm_stack_end - &vmm_stack_start,
45                    RT_THREAD_PRIORITY_MAX - 1, 10);
46 
47     /* set thread to ready status but not switch to */
48     rt_thread_startup(thread);
49 
50     /* set current thread as vmm thread */
51     rt_current_thread = thread;
52 }
53 
54 #ifdef VMM_VERIFY_GUEST
_verify_guest(void * p)55 static void _verify_guest(void *p)
56 {
57     while (1)
58     {
59         rt_thread_delay(RT_TICK_PER_SECOND/4);
60         vmm_verify_guest_status(vmm_thread.sp);
61     }
62 }
63 
vmm_create_monitor(void)64 static void vmm_create_monitor(void)
65 {
66     rt_thread_t tid;
67 
68     tid = rt_thread_create("vmon",
69                            _verify_guest, RT_NULL,
70                            1024, 8, 20);
71     if (tid)
72         rt_thread_startup(tid);
73 }
74 #endif
75 
76 #ifdef RT_VMM_USING_DOMAIN
77 extern unsigned long guest_domain_val;
78 extern unsigned long vmm_domain_val;
79 #endif
80 
81 static void vmm_entry_glue(rt_uint32_t level,
82                            unsigned int vmm_domain,
83                            unsigned int kernel_domain)
84     /* inline would make the section setting meaningless */
85     __attribute__((noinline))
86     SECTION(".vmm_glue");
vmm_entry_glue(rt_uint32_t level,unsigned int vmm_domain,unsigned int kernel_domain)87 static void vmm_entry_glue(rt_uint32_t level,
88                            unsigned int vmm_domain,
89                            unsigned int kernel_domain)
90 {
91     rt_schedule();
92 
93 #ifdef RT_VMM_USING_DOMAIN
94     /* protect us from the guest code, but leave the shared region permission
95      */
96     guest_domain_val &= ~(0x3 << (vmm_domain * 2));
97 
98     /* don't touch the guest kernel space */
99     vmm_domain_val &= ~(0x3 << (kernel_domain * 2));
100 #endif
101 
102     rt_hw_interrupt_enable(level);
103 }
104 
vmm_entry(struct vmm_entry_param * param)105 void vmm_entry(struct vmm_entry_param *param)
106 {
107     rt_uint32_t level;
108 
109     level = rt_hw_interrupt_disable();
110 
111     /* set iomap */
112     vmm_iomap_init(param->iomap);
113 
114     /* set VMM context address */
115     vmm_context_init(&RT_VMM_SHARE->ctx);
116 
117     /* init hardware interrupt */
118     rt_hw_interrupt_init();
119 
120     vmm_vector_init();
121 
122     /* init board */
123     rt_hw_board_init();
124 
125 #ifdef RT_USING_LOGTRACE
126     /* Some parts of VMM use log_trace, so we need to init it right after
127      * board_init. */
128     log_trace_init();
129     log_trace_set_device(RT_CONSOLE_DEVICE_NAME);
130 
131     log_trace_register_session(&_lgs);
132 #endif
133 
134     /* show version */
135     rt_show_version();
136     rt_kprintf("share ctx: %p(%x)\n",
137                &RT_VMM_SHARE->ctx, sizeof(RT_VMM_SHARE->ctx));
138 
139     /* init timer system */
140     rt_system_timer_init();
141 
142     {
143         rt_uint32_t ttbr;
144         asm volatile ("mrc p15, 0, %0, c2, c0, 0\n"
145                       : "=r"(ttbr));
146         rt_kprintf("Linux TTBR: 0x%08x\n", ttbr);
147         /*
148          *rt_hw_cpu_dump_page_table((void*)((ttbr & (0xffffc000))
149          *                                  - 0x80000000 + 0xC0000000));
150          */
151         /*rt_hw_cpu_dump_page_table((void*)(0xc0004000));*/
152     }
153 
154 #ifdef RT_VMM_USING_DOMAIN
155     vmm_context_init_domain(param->domain);
156 #endif
157 
158     rt_kprintf("heap: 0x%p - 0x%p, %dKi bytes\n",
159                (void*)HEAP_BEGIN, (void*)HEAP_END,
160                ((int)HEAP_END - (int)HEAP_BEGIN) / 1024);
161     /* init heap memory system */
162     rt_system_heap_init((void*)HEAP_BEGIN, (void*)HEAP_END);
163 
164     /* init scheduler system */
165     rt_system_scheduler_init();
166 
167     rt_kprintf("user application init.\n");
168     /* init application */
169     rt_application_init();
170 
171 #ifdef VMM_VERIFY_GUEST
172     vmm_create_monitor();
173 #endif
174 
175     rt_system_timer_thread_init();
176 
177     vmm_thread_init(&vmm_thread, "vmm");
178 
179 #ifdef RT_VMM_USING_DOMAIN
180     rt_kprintf("domain protect present\n");
181 #endif
182     /* start scheduler */
183     rt_kprintf("do the first scheduling...\n");
184 
185     vmm_entry_glue(level,
186                    param->domain->vmm,
187                    param->domain->kernel);
188 }
189 
190