arch_030_cpu.cpp revision a3dc7ef0
14e44040dSFrançois Revol/*
24e44040dSFrançois Revol * Copyright 2003-2007, Haiku Inc. All rights reserved.
34e44040dSFrançois Revol * Distributed under the terms of the MIT License.
44e44040dSFrançois Revol *
54e44040dSFrançois Revol * Authors:
64e44040dSFrançois Revol * 		Fran��ois Revol <revol@free.fr>
74e44040dSFrançois Revol */
84e44040dSFrançois Revol
94e44040dSFrançois Revol#include <KernelExport.h>
104e44040dSFrançois Revol
114e44040dSFrançois Revol#include <arch_platform.h>
124e44040dSFrançois Revol#include <arch_thread.h>
134e44040dSFrançois Revol#include <arch/cpu.h>
144e44040dSFrançois Revol#include <boot/kernel_args.h>
154e44040dSFrançois Revol
164e44040dSFrançois Revol#ifdef __cplusplus
174e44040dSFrançois Revolextern "C" {
184e44040dSFrançois Revol#endif
194e44040dSFrançois Revol
204e44040dSFrançois Revol/* from arch_030_asm.S */
214e44040dSFrançois Revolextern void flush_insn_pipeline_030(void);
224e44040dSFrançois Revolextern void flush_atc_all_030(void);
23a3dc7ef0SFrançois Revolextern void flush_atc_addr_030(addr_t addr);
244e44040dSFrançois Revol
254e44040dSFrançois Revol#ifdef __cplusplus
264e44040dSFrançois Revol}
274e44040dSFrançois Revol#endif
284e44040dSFrançois Revol
294e44040dSFrançois Revol
304e44040dSFrançois Revol
314e44040dSFrançois Revol#define CACHELINE 16
324e44040dSFrançois Revol
334e44040dSFrançois Revolstatic void
34a3dc7ef0SFrançois Revolsync_icache_030(addr_t address, size_t len)
354e44040dSFrançois Revol{
364e44040dSFrançois Revol	int l, off;
374e44040dSFrançois Revol	char *p;
384e44040dSFrançois Revol	uint32 cacr;
394e44040dSFrançois Revol
404e44040dSFrançois Revol	off = (unsigned int)address & (CACHELINE - 1);
414e44040dSFrançois Revol	len += off;
424e44040dSFrançois Revol
434e44040dSFrançois Revol	l = len;
444e44040dSFrançois Revol	p = (char *)address - off;
454e44040dSFrançois Revol	asm volatile ("nop");
464e44040dSFrançois Revol	asm volatile ("movec %%cacr,%0" : "=r"(cacr):);
474e44040dSFrançois Revol	cacr |= 0x00000004; /* ClearInstructionCacheEntry */
484e44040dSFrançois Revol	do {
494e44040dSFrançois Revol		/* the 030 invalidates only 1 long of the cache line */
504e44040dSFrançois Revol		//XXX: what about 040 and 060 ?
514e44040dSFrançois Revol		asm volatile ("movec %0,%%caar\n"		\
524e44040dSFrançois Revol					  "movec %1,%%cacr\n"		\
534e44040dSFrançois Revol					  "addq.l #4,%0\n"			\
544e44040dSFrançois Revol					  "movec %0,%%caar\n"		\
554e44040dSFrançois Revol					  "movec %1,%%cacr\n"		\
564e44040dSFrançois Revol					  "addq.l #4,%0\n"			\
574e44040dSFrançois Revol					  "movec %0,%%caar\n"		\
584e44040dSFrançois Revol					  "movec %1,%%cacr\n"		\
594e44040dSFrançois Revol					  "addq.l #4,%0\n"			\
604e44040dSFrançois Revol					  "movec %0,%%caar\n"		\
614e44040dSFrançois Revol					  "movec %1,%%cacr\n"		\
624e44040dSFrançois Revol					  :: "r"(p), "r"(cacr));
634e44040dSFrançois Revol		p += CACHELINE;
644e44040dSFrançois Revol	} while ((l -= CACHELINE) > 0);
654e44040dSFrançois Revol	asm volatile ("nop");
664e44040dSFrançois Revol}
674e44040dSFrançois Revol
684e44040dSFrançois Revol
694e44040dSFrançois Revolstruct m68k_cpu_ops cpu_ops_030 = {
704e44040dSFrançois Revol	&flush_insn_pipeline_030,
714e44040dSFrançois Revol	&flush_atc_all_030,
724e44040dSFrançois Revol	&flush_atc_all_030, // no global flag, so no useronly flushing
734e44040dSFrançois Revol	&flush_atc_addr_030,
744e44040dSFrançois Revol	&sync_icache_030, // dcache is the same
754e44040dSFrançois Revol	&sync_icache_030,
764e44040dSFrançois Revol	NULL // idle
774e44040dSFrançois Revol};
78