vfs: check userland buffers before reading them.
[haiku.git] / src / system / kernel / arch / m68k / arch_cpu.cpp
blob8017cb9c850f7b77bc2c76c111cfa7da0703625e
1 /*
2 * Copyright 2007, François Revol, revol@free.fr.
3 * Distributed under the terms of the MIT License.
5 * Copyright 2003-2005, Axel Dörfler, axeld@pinc-software.de.
6 * Distributed under the terms of the MIT License.
8 * Copyright 2001, Travis Geiselbrecht. All rights reserved.
9 * Distributed under the terms of the NewOS License.
13 #include <KernelExport.h>
15 #include <arch_platform.h>
16 #include <arch_thread.h>
17 #include <arch/cpu.h>
18 #include <boot/kernel_args.h>
19 #include <commpage.h>
20 #include <elf.h>
22 extern struct m68k_cpu_ops cpu_ops_030;
23 extern struct m68k_cpu_ops cpu_ops_040;
24 extern struct m68k_cpu_ops cpu_ops_060;
26 struct m68k_cpu_ops cpu_ops;
28 int arch_cpu_type;
29 int arch_fpu_type;
30 int arch_mmu_type;
31 int arch_platform;
33 status_t
34 arch_cpu_preboot_init_percpu(kernel_args *args, int curr_cpu)
36 // enable FPU
37 //ppc:set_msr(get_msr() | MSR_FP_AVAILABLE);
39 // The current thread must be NULL for all CPUs till we have threads.
40 // Some boot code relies on this.
41 arch_thread_set_current_thread(NULL);
43 return B_OK;
47 status_t
48 arch_cpu_init_percpu(kernel_args *args, int curr_cpu)
50 //detect_cpu(curr_cpu);
52 // we only support one anyway...
53 return 0;
57 status_t
58 arch_cpu_init(kernel_args *args)
60 arch_cpu_type = args->arch_args.cpu_type;
61 arch_fpu_type = args->arch_args.fpu_type;
62 arch_mmu_type = args->arch_args.mmu_type;
63 arch_platform = args->arch_args.platform;
64 arch_platform = args->arch_args.machine;
66 switch (arch_cpu_type) {
67 case 68020:
68 case 68030:
69 memcpy(&cpu_ops, &cpu_ops_030, sizeof(cpu_ops));
70 break;
72 case 68040:
73 memcpy(&cpu_ops, &cpu_ops_040, sizeof(cpu_ops));
74 break;
76 #ifdef SUPPORTS_060
77 case 68060:
78 memcpy(&cpu_ops, &cpu_ops_060, sizeof(cpu_ops));
79 break;
80 #endif
81 default:
82 panic("unknown cpu_type %d\n", arch_cpu_type);
85 return B_OK;
89 status_t
90 arch_cpu_init_post_vm(kernel_args *args)
92 return B_OK;
95 status_t
96 arch_cpu_init_post_modules(kernel_args *args)
98 // add the functions to the commpage image
99 image_id image = get_commpage_image();
101 return B_OK;
105 void
106 arch_cpu_sync_icache(void *address, size_t len)
108 cpu_ops.flush_icache((addr_t)address, len);
112 void
113 arch_cpu_memory_read_barrier(void)
115 asm volatile ("nop;" : : : "memory");
116 #warning M68k: check arch_cpu_memory_read_barrier (FNOP ?)
120 void
121 arch_cpu_memory_write_barrier(void)
123 asm volatile ("nop;" : : : "memory");
124 #warning M68k: check arch_cpu_memory_write_barrier (FNOP ?)
128 void
129 arch_cpu_invalidate_TLB_range(addr_t start, addr_t end)
131 int32 num_pages = end / B_PAGE_SIZE - start / B_PAGE_SIZE;
132 cpu_ops.flush_insn_pipeline();
133 while (num_pages-- >= 0) {
134 cpu_ops.flush_atc_addr(start);
135 cpu_ops.flush_insn_pipeline();
136 start += B_PAGE_SIZE;
138 cpu_ops.flush_insn_pipeline();
142 void
143 arch_cpu_invalidate_TLB_list(addr_t pages[], int num_pages)
145 int i;
147 cpu_ops.flush_insn_pipeline();
148 for (i = 0; i < num_pages; i++) {
149 cpu_ops.flush_atc_addr(pages[i]);
150 cpu_ops.flush_insn_pipeline();
152 cpu_ops.flush_insn_pipeline();
156 void
157 arch_cpu_global_TLB_invalidate(void)
159 cpu_ops.flush_insn_pipeline();
160 cpu_ops.flush_atc_all();
161 cpu_ops.flush_insn_pipeline();
165 void
166 arch_cpu_user_TLB_invalidate(void)
168 cpu_ops.flush_insn_pipeline();
169 cpu_ops.flush_atc_user();
170 cpu_ops.flush_insn_pipeline();
174 status_t
175 arch_cpu_shutdown(bool reboot)
177 M68KPlatform::Default()->ShutDown(reboot);
178 return B_ERROR;
182 // The purpose of this function is to trick the compiler. When setting the
183 // page_handler to a label that is obviously (to the compiler) never used,
184 // it may reorganize the control flow, so that the labeled part is optimized
185 // away.
186 // By invoking the function like this
188 // if (m68k_set_fault_handler(faultHandler, (addr_t)&&error))
189 // goto error;
191 // the compiler has to keep the labeled code, since it can't guess the return
192 // value of this (non-inlinable) function. At least in my tests it worked that
193 // way, and I hope it will continue to work like this in the future.
195 bool
196 m68k_set_fault_handler(addr_t *handlerLocation, addr_t handler)
198 // TODO: This doesn't work correctly with gcc 4 anymore!
199 *handlerLocation = handler;
200 return false;