comparison src/start.c @ 0:83c23a36980d

Init
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Fri, 26 May 2017 23:11:05 +0900
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:83c23a36980d
1 // initialize section
2 #include "types.h"
3 #include "param.h"
4 #include "arm.h"
5 #include "mmu.h"
6 #include "defs.h"
7 #include "memlayout.h"
8
9 void _uart_putc(int c)
10 {
11 volatile uint8 * uart0 = (uint8*)UART0;
12 *uart0 = c;
13 }
14
15
16 void _puts (char *s)
17 {
18 while (*s != '\0') {
19 _uart_putc(*s);
20 s++;
21 }
22 }
23
24 void _putint (char *prefix, uint val, char* suffix)
25 {
26 char* arr = "0123456789ABCDEF";
27 int idx;
28
29 if (prefix) {
30 _puts(prefix);
31 }
32
33 for (idx = sizeof(val) * 8 - 4; idx >= 0; idx -= 4) {
34 _uart_putc(arr[(val >> idx) & 0x0F]);
35 }
36
37 if (suffix) {
38 _puts(suffix);
39 }
40 }
41
42
43 // kernel page table, reserved in the kernel.ld
44 extern uint32 _kernel_pgtbl;
45 extern uint32 _user_pgtbl;
46
47 uint32 *kernel_pgtbl = &_kernel_pgtbl;
48 uint32 *user_pgtbl = &_user_pgtbl;
49
50 #define PDE_SHIFT 20
51
52 uint32 get_pde (uint32 virt)
53 {
54 virt >>= PDE_SHIFT;
55 return kernel_pgtbl[virt];
56 }
57
58 // setup the boot page table: dev_mem whether it is device memory
59 void set_bootpgtbl (uint32 virt, uint32 phy, uint len, int dev_mem )
60 {
61 uint32 pde;
62 int idx;
63
64 // convert all the parameters to indexes
65 virt >>= PDE_SHIFT;
66 phy >>= PDE_SHIFT;
67 len >>= PDE_SHIFT;
68
69 for (idx = 0; idx < len; idx++) {
70 pde = (phy << PDE_SHIFT);
71
72 if (!dev_mem) {
73 // normal memory, make it kernel-only, cachable, bufferable
74 pde |= (AP_KO << 10) | PE_CACHE | PE_BUF | KPDE_TYPE;
75 } else {
76 // device memory, make it non-cachable and non-bufferable
77 pde |= (AP_KO << 10) | KPDE_TYPE;
78 }
79
80 // use different page table for user/kernel space
81 if (virt < NUM_UPDE) {
82 user_pgtbl[virt] = pde;
83 } else {
84 kernel_pgtbl[virt] = pde;
85 }
86
87 virt++;
88 phy++;
89 }
90 }
91
92 static void _flush_all (void)
93 {
94 uint val = 0;
95
96 // flush all TLB
97 asm("MCR p15, 0, %[r], c8, c7, 0" : :[r]"r" (val):);
98
99 // invalid entire data and instruction cache
100 // asm ("MCR p15,0,%[r],c7,c5,0": :[r]"r" (val):);
101 // asm ("MCR p15,0,%[r],c7,c6,0": :[r]"r" (val):);
102 }
103
104 void load_pgtlb (uint32* kern_pgtbl, uint32* user_pgtbl)
105 {
106 uint ret;
107 char arch;
108 uint val;
109
110 // read the main id register to make sure we are running on ARMv6
111 asm("MRC p15, 0, %[r], c0, c0, 0": [r]"=r" (ret)::);
112
113 if (ret >> 24 == 0x41) {
114 //_puts ("ARM-based CPU\n");
115 }
116
117 arch = (ret >> 16) & 0x0F;
118
119 if ((arch != 7) && (arch != 0xF)) {
120 _puts ("need AARM v6 or higher\n");
121 }
122
123 // we need to check the cache/tlb etc., but let's skip it for now
124
125 // set domain access control: all domain will be checked for permission
126 val = 0x55555555;
127 asm("MCR p15, 0, %[v], c3, c0, 0": :[v]"r" (val):);
128
129 // set the page table base registers. We use two page tables: TTBR0
130 // for user space and TTBR1 for kernel space
131 val = 32 - UADDR_BITS;
132 asm("MCR p15, 0, %[v], c2, c0, 2": :[v]"r" (val):);
133
134 // set the kernel page table
135 val = (uint)kernel_pgtbl | 0x00;
136 asm("MCR p15, 0, %[v], c2, c0, 1": :[v]"r" (val):);
137
138 // set the user page table
139 val = (uint)user_pgtbl | 0x00;
140 asm("MCR p15, 0, %[v], c2, c0, 0": :[v]"r" (val):);
141
142 // ok, enable paging using read/modify/write
143 asm("MRC p15, 0, %[r], c1, c0, 0": [r]"=r" (val)::);
144
145 val |= 0x80300D; // enable MMU, cache, write buffer, high vector tbl,
146 // disable subpage
147 asm("MCR p15, 0, %[r], c1, c0, 0": :[r]"r" (val):);
148
149 _flush_all();
150 }
151
152 extern void * edata_entry;
153 extern void * svc_stktop;
154 extern void kmain (void);
155 extern void jump_stack (void);
156
157 extern void * edata;
158 extern void * end;
159
160 // clear the BSS section for the main kernel, see kernel.ld
161 void clear_bss (void)
162 {
163 memset(&edata, 0x00, (uint)&end-(uint)&edata);
164 }
165
166 void start (void)
167 {
168 uint32 vectbl;
169 _puts("starting xv6 for ARM...\n");
170
171 // double map the low memory, required to enable paging
172 // we do not map all the physical memory
173 set_bootpgtbl(0, 0, INIT_KERNMAP, 0);
174 set_bootpgtbl(KERNBASE, 0, INIT_KERNMAP, 0);
175
176 // vector table is in the middle of first 1MB (0xF000)
177 vectbl = P2V_WO (VEC_TBL & PDE_MASK);
178
179 if (vectbl <= (uint)&end) {
180 cprintf ("error: vector table overlaps kernel\n");
181 }
182
183 set_bootpgtbl(VEC_TBL, 0, 1 << PDE_SHIFT, 0);
184 set_bootpgtbl(KERNBASE+DEVBASE, DEVBASE, DEV_MEM_SZ, 1);
185
186 load_pgtlb (kernel_pgtbl, user_pgtbl);
187 jump_stack ();
188
189 // We can now call normal kernel functions at high memory
190 clear_bss ();
191
192 kmain ();
193 }