136ee9f5cSFrançois Revol/*
236ee9f5cSFrançois Revol * Copyright 2003-2008, Haiku Inc. All rights reserved.
336ee9f5cSFrançois Revol * Distributed under the terms of the MIT License.
436ee9f5cSFrançois Revol *
536ee9f5cSFrançois Revol * Authors:
636ee9f5cSFrançois Revol * 		Fran��ois Revol <revol@free.fr>
736ee9f5cSFrançois Revol */
836ee9f5cSFrançois Revol
936ee9f5cSFrançois Revol#include <KernelExport.h>
1036ee9f5cSFrançois Revol
1136ee9f5cSFrançois Revol#include <arch_platform.h>
1236ee9f5cSFrançois Revol#include <arch_thread.h>
1336ee9f5cSFrançois Revol#include <arch/cpu.h>
1436ee9f5cSFrançois Revol#include <boot/kernel_args.h>
1536ee9f5cSFrançois Revol
1636ee9f5cSFrançois Revol#ifdef __cplusplus
1736ee9f5cSFrançois Revolextern "C" {
1836ee9f5cSFrançois Revol#endif
1936ee9f5cSFrançois Revol
2036ee9f5cSFrançois Revol/* from arch_040_asm.S */
2136ee9f5cSFrançois Revolextern void flush_insn_pipeline_040(void);
2236ee9f5cSFrançois Revolextern void flush_atc_all_040(void);
2336ee9f5cSFrançois Revolextern void flush_atc_user_040(void);
2436ee9f5cSFrançois Revolextern void flush_atc_addr_040(addr_t addr);
2536ee9f5cSFrançois Revol
2636ee9f5cSFrançois Revol#ifdef __cplusplus
2736ee9f5cSFrançois Revol}
2836ee9f5cSFrançois Revol#endif
2936ee9f5cSFrançois Revol
3036ee9f5cSFrançois Revol
3136ee9f5cSFrançois Revol
3236ee9f5cSFrançois Revol#define CACHELINE 16
3336ee9f5cSFrançois Revol
3436ee9f5cSFrançois Revolstatic void
3536ee9f5cSFrançois Revolsync_icache_040(addr_t address, size_t len)
3636ee9f5cSFrançois Revol{
3736ee9f5cSFrançois Revol	int l, off;
3836ee9f5cSFrançois Revol	char *p;
3936ee9f5cSFrançois Revol
4036ee9f5cSFrançois Revol	off = (unsigned int)address & (CACHELINE - 1);
4136ee9f5cSFrançois Revol	len += off;
4236ee9f5cSFrançois Revol
4336ee9f5cSFrançois Revol	l = len;
4436ee9f5cSFrançois Revol	p = (char *)address - off;
4536ee9f5cSFrançois Revol	asm volatile ("nop");
4636ee9f5cSFrançois Revol
4736ee9f5cSFrançois Revol#warning M68K: 040: use CPUSHP on pages when possible for speed.
4836ee9f5cSFrançois Revol	do {
4936ee9f5cSFrançois Revol		asm volatile (		\
5036ee9f5cSFrançois Revol					  "cpushl %%ic,(%0)\n"		\
5136ee9f5cSFrançois Revol					  :: "a"(p));
5236ee9f5cSFrançois Revol		p += CACHELINE;
5336ee9f5cSFrançois Revol	} while ((l -= CACHELINE) > 0);
5436ee9f5cSFrançois Revol	asm volatile ("nop");
5536ee9f5cSFrançois Revol}
5636ee9f5cSFrançois Revol
5736ee9f5cSFrançois Revol
5836ee9f5cSFrançois Revolstatic void
5936ee9f5cSFrançois Revolsync_dcache_040(addr_t address, size_t len)
6036ee9f5cSFrançois Revol{
6136ee9f5cSFrançois Revol	int l, off;
6236ee9f5cSFrançois Revol	char *p;
6336ee9f5cSFrançois Revol
6436ee9f5cSFrançois Revol	off = (unsigned int)address & (CACHELINE - 1);
6536ee9f5cSFrançois Revol	len += off;
6636ee9f5cSFrançois Revol
6736ee9f5cSFrançois Revol	l = len;
6836ee9f5cSFrançois Revol	p = (char *)address - off;
6936ee9f5cSFrançois Revol	asm volatile ("nop");
7036ee9f5cSFrançois Revol
7136ee9f5cSFrançois Revol#warning M68K: 040: use CPUSHP on pages when possible for speed.
7236ee9f5cSFrançois Revol	do {
7336ee9f5cSFrançois Revol		asm volatile (		\
7436ee9f5cSFrançois Revol					  "cpushl %%dc,(%0)\n"		\
7536ee9f5cSFrançois Revol					  :: "a"(p));
7636ee9f5cSFrançois Revol		p += CACHELINE;
7736ee9f5cSFrançois Revol	} while ((l -= CACHELINE) > 0);
7836ee9f5cSFrançois Revol	asm volatile ("nop");
7936ee9f5cSFrançois Revol}
8036ee9f5cSFrançois Revol
8136ee9f5cSFrançois Revol
8236ee9f5cSFrançois Revolstruct m68k_cpu_ops cpu_ops_040 = {
8336ee9f5cSFrançois Revol	&flush_insn_pipeline_040,
8436ee9f5cSFrançois Revol	&flush_atc_all_040,
8536ee9f5cSFrançois Revol	&flush_atc_user_040,
8636ee9f5cSFrançois Revol	&flush_atc_addr_040,
8736ee9f5cSFrançois Revol	&sync_dcache_040,
8836ee9f5cSFrançois Revol	&sync_icache_040,
8936ee9f5cSFrançois Revol	NULL // idle
9036ee9f5cSFrançois Revol};
91