vfs: check userland buffers before reading them.
[haiku.git] / src / system / boot / arch / m68k / mmu_030.cpp
blob699e75e2f9117f107a00cc9153b6a00e9b7b60e0
1 /*
2 * Copyright 2004-2007, Axel Dörfler, axeld@pinc-software.de.
3 * Based on code written by Travis Geiselbrecht for NewOS.
5 * Distributed under the terms of the MIT License.
6 */
9 #include "mmu.h"
11 #include <boot/platform.h>
12 #include <boot/stdio.h>
13 #include <boot/kernel_args.h>
14 #include <boot/stage2.h>
15 #include <arch/cpu.h>
16 #include <arch_kernel.h>
17 #include <kernel.h>
19 #include <OS.h>
21 #include <string.h>
23 #include "arch_030_mmu.h"
26 #define TRACE_MMU
27 #ifdef TRACE_MMU
28 # define TRACE(x) dprintf x
29 #else
30 # define TRACE(x) ;
31 #endif
34 extern page_root_entry *gPageRoot;
37 static void
38 initialize(void)
40 TRACE(("mmu_030:initialize\n"));
44 static status_t
45 set_tt(int which, addr_t pa, size_t len, uint32 perms)
47 TRACE(("mmu_030:set_tt(%d, 0x%lx, 0x%lx, 0x%08lx)\n", which, pa, len, perms));
48 uint32 mask;
49 uint32 ttr = 0;
50 mask = 0x0000ffff;
51 if (len) {
52 len = (len >> 24) & 0x00ff;
53 while (len >>= 1)
54 mask <<= 1;
55 // enable, cachable(?), r/w
56 // super only
57 // mc68030 user's manual, page 9-57
58 ttr = 0x08043;
59 ttr |= (pa & 0xff000000);
60 ttr |= (mask & 0x00ff0000);
62 TRACE(("mmu_030:set_tt: 0x%08lx\n", ttr));
64 /* as seen in linux and BSD code,
65 * we need to use .chip pseudo op here as -m68030 doesn't seem to help gas grok it.
67 switch (which) {
68 case 0:
69 asm volatile( \
70 ".chip 68030\n\t" \
71 "pmove %%tt0,(%0)\n\t" \
72 ".chip 68k\n\t" \
73 : : "a"(&ttr));
74 break;
75 case 1:
76 asm volatile( \
77 ".chip 68030\n\t" \
78 "pmove (%0),%%tt1\n" \
79 ".chip 68k\n\t" \
80 : : "a"(&ttr));
81 break;
82 default:
83 return EINVAL;
85 return B_OK;
89 static status_t
90 load_rp(addr_t pa)
92 TRACE(("mmu_030:load_rp(0x%lx)\n", pa));
93 long_page_directory_entry entry;
94 *(uint64 *)&entry = DFL_PAGEENT_VAL;
95 entry.type = DT_ROOT;
96 entry.addr = TA_TO_PREA(((addr_t)pa));
98 asm volatile( \
99 "pmove (%0),%%srp\n" \
100 "pmove (%0),%%crp\n" \
101 : : "a"((uint64 *)&entry));
102 return B_OK;
106 static status_t
107 allocate_kernel_pgdirs(void)
109 page_root_entry *pr = gPageRoot;
110 page_directory_entry *pd;
111 addr_t tbl;
112 int i;
114 // we'll fill in the 2nd half with ready made page dirs
115 for (i = NUM_ROOTENT_PER_TBL/2; i < NUM_ROOTENT_PER_TBL; i++) {
116 if (i % NUM_DIRTBL_PER_PAGE)
117 tbl += SIZ_DIRTBL;
118 else
119 tbl = mmu_get_next_page_tables();
120 pr[i].addr = TA_TO_PREA(tbl);
121 pr[i].type = DT_ROOT;
122 pd = (page_directory_entry *)tbl;
123 for (int32 j = 0; j < NUM_DIRENT_PER_TBL; j++)
124 *(page_directory_entry_scalar *)(&pd[j]) = DFL_DIRENT_VAL;
126 return B_OK;
130 static status_t
131 enable_paging(void)
133 TRACE(("mmu_030:enable_paging\n"));
134 return B_NO_INIT;
138 const struct boot_mmu_ops k030MMUOps = {
139 &initialize,
140 &set_tt,
141 &load_rp,
142 &allocate_kernel_pgdirs,
143 &enable_paging