xref: /haiku/src/system/kernel/arch/m68k/arch_030_cpu.cpp (revision e6b30aee0fd7a23d6a6baab9f3718945a0cd838a)
1 /*
2  * Copyright 2003-2007, Haiku Inc. All rights reserved.
3  * Distributed under the terms of the MIT License.
4  *
5  * Authors:
6  * 		François Revol <revol@free.fr>
7  */
8 
9 #include <KernelExport.h>
10 
11 #include <arch_platform.h>
12 #include <arch_thread.h>
13 #include <arch/cpu.h>
14 #include <boot/kernel_args.h>
15 
16 #ifdef __cplusplus
17 extern "C" {
18 #endif
19 
20 /* from arch_030_asm.S */
21 extern void flush_insn_pipeline_030(void);
22 extern void flush_atc_all_030(void);
23 extern void flush_atc_addr_030(void *addr);
24 
25 #ifdef __cplusplus
26 }
27 #endif
28 
29 
30 
31 #define CACHELINE 16
32 
33 static void
34 sync_icache_030(void *address, size_t len)
35 {
36 	int l, off;
37 	char *p;
38 	uint32 cacr;
39 
40 	off = (unsigned int)address & (CACHELINE - 1);
41 	len += off;
42 
43 	l = len;
44 	p = (char *)address - off;
45 	asm volatile ("nop");
46 	asm volatile ("movec %%cacr,%0" : "=r"(cacr):);
47 	cacr |= 0x00000004; /* ClearInstructionCacheEntry */
48 	do {
49 		/* the 030 invalidates only 1 long of the cache line */
50 		//XXX: what about 040 and 060 ?
51 		asm volatile ("movec %0,%%caar\n"		\
52 					  "movec %1,%%cacr\n"		\
53 					  "addq.l #4,%0\n"			\
54 					  "movec %0,%%caar\n"		\
55 					  "movec %1,%%cacr\n"		\
56 					  "addq.l #4,%0\n"			\
57 					  "movec %0,%%caar\n"		\
58 					  "movec %1,%%cacr\n"		\
59 					  "addq.l #4,%0\n"			\
60 					  "movec %0,%%caar\n"		\
61 					  "movec %1,%%cacr\n"		\
62 					  :: "r"(p), "r"(cacr));
63 		p += CACHELINE;
64 	} while ((l -= CACHELINE) > 0);
65 	asm volatile ("nop");
66 }
67 
68 
69 struct m68k_cpu_ops cpu_ops_030 = {
70 	&flush_insn_pipeline_030,
71 	&flush_atc_all_030,
72 	&flush_atc_all_030, // no global flag, so no useronly flushing
73 	&flush_atc_addr_030,
74 	&sync_icache_030, // dcache is the same
75 	&sync_icache_030,
76 	NULL // idle
77 };
78