#include "opt_m68k_arch.h"
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: sys_machdep.c,v 1.19 2026/05/06 04:45:04 thorpej Exp $");
#include <sys/param.h>
#include <sys/proc.h>
#include <sys/mount.h>
#include <uvm/uvm_extern.h>
#include <sys/syscallargs.h>
#include <machine/cpu.h>
#ifndef __mc68010__
#include <m68k/cacheops.h>
#define CC_PURGE 1
#define CC_FLUSH 2
#define CC_IPURGE 4
#define CC_EXTPURGE 0x80000000
int
cachectl1(u_long req, vaddr_t addr, size_t len, struct proc *p)
{
int error = 0;
#if defined(M68040) || defined(M68060)
if (cputype >= CPU_68040) {
int inc = 0;
bool doall = false;
paddr_t pa = 0;
vaddr_t end = 0;
if (addr == 0 ||
#if defined(M68060)
(cputype == CPU_68040 && req & CC_IPURGE) ||
#else
(req & CC_IPURGE) ||
#endif
((req & ~CC_EXTPURGE) != CC_PURGE && len > 2 * PAGE_SIZE))
doall = 1;
if (!doall) {
end = addr + len;
if (len <= 1024) {
addr = addr & ~0xf;
inc = 16;
} else {
addr = m68k_trunc_page(addr);
inc = PAGE_SIZE;
}
}
do {
if (!doall &&
(pa == 0 || m68k_page_offset(addr) == 0)) {
if (pmap_extract(p->p_vmspace->vm_map.pmap,
addr, &pa) == false)
doall = 1;
}
switch (req) {
case CC_EXTPURGE|CC_IPURGE:
case CC_IPURGE:
if (doall) {
DCFA();
ICPA();
} else if (inc == 16) {
DCFL(pa);
ICPL(pa);
} else if (inc == PAGE_SIZE) {
DCFP(pa);
ICPP(pa);
}
break;
case CC_EXTPURGE|CC_PURGE:
case CC_PURGE:
if (doall)
DCFA();
else if (inc == 16)
DCPL(pa);
else if (inc == PAGE_SIZE)
DCPP(pa);
break;
case CC_EXTPURGE|CC_FLUSH:
case CC_FLUSH:
if (doall)
DCFA();
else if (inc == 16)
DCFL(pa);
else if (inc == PAGE_SIZE)
DCFP(pa);
break;
default:
error = EINVAL;
break;
}
if (doall)
break;
pa += inc;
addr += inc;
} while (addr < end);
return (error);
}
#endif
switch (req) {
case CC_EXTPURGE|CC_PURGE:
case CC_EXTPURGE|CC_FLUSH:
#if defined(M68K_EC_PAC)
if (ectype == EC_PHYS)
PCIA();
#endif
case CC_PURGE:
case CC_FLUSH:
DCIU();
break;
case CC_EXTPURGE|CC_IPURGE:
#if defined(M68K_EC_PAC)
if (ectype == EC_PHYS)
PCIA();
else
#endif
DCIU();
case CC_IPURGE:
ICIA();
break;
default:
error = EINVAL;
break;
}
return error;
}
#if defined(amiga) || defined(x68k)
int
dma_cachectl(void *addr, int len)
{
#if defined(M68040) || defined(M68060)
int inc = 0;
int pa = 0;
void *end;
if (mmutype != MMU_68040) {
return 0;
}
end = (char*)addr + len;
if (len <= 1024) {
addr = (void *)((vaddr_t)addr & ~0xf);
inc = 16;
} else {
addr = (void *)m68k_trunc_page(addr);
inc = PAGE_SIZE;
}
do {
if (pa == 0 || ((vaddr_t)addr & PAGE_MASK) == 0) {
pa = kvtop(addr);
}
if (inc == 16) {
DCFL(pa);
ICPL(pa);
} else {
DCFP(pa);
ICPP(pa);
}
pa += inc;
addr = (char*)addr + inc;
} while (addr < end);
#endif
return 0;
}
#endif
#endif
int
sys_sysarch(struct lwp *l, const struct sys_sysarch_args *uap,
register_t *retval)
{
return ENOSYS;
}