diff options
-rw-r--r-- | lib/libarch/Makefile | 4 | ||||
-rw-r--r-- | lib/libarch/mips64/Makefile | 13 | ||||
-rw-r--r-- | lib/libarch/mips64/cacheflush.3 | 81 | ||||
-rw-r--r-- | lib/libc/arch/mips64/gen/Makefile.inc | 3 | ||||
-rw-r--r-- | lib/libc/arch/mips64/gen/cacheflush.c | 37 | ||||
-rw-r--r-- | sys/arch/mips64/include/sysarch.h | 50 | ||||
-rw-r--r-- | sys/arch/mips64/mips64/sys_machdep.c | 78 | ||||
-rw-r--r-- | sys/arch/sgi/include/sysarch.h | 3 |
8 files changed, 264 insertions, 5 deletions
diff --git a/lib/libarch/Makefile b/lib/libarch/Makefile index 88410ed5217..c915d1b338b 100644 --- a/lib/libarch/Makefile +++ b/lib/libarch/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.7 2005/02/03 17:13:46 drahn Exp $ +# $OpenBSD: Makefile,v 1.8 2009/09/27 18:20:11 miod Exp $ # $NetBSD: Makefile,v 1.8 1996/02/21 02:43:52 jtk Exp $ -SUBDIR= alpha i386 amd64 arm +SUBDIR= alpha amd64 arm i386 mips64 .include <bsd.subdir.mk> diff --git a/lib/libarch/mips64/Makefile b/lib/libarch/mips64/Makefile new file mode 100644 index 00000000000..8a33d4ce0d7 --- /dev/null +++ b/lib/libarch/mips64/Makefile @@ -0,0 +1,13 @@ +# $OpenBSD: Makefile,v 1.1 2009/09/27 18:20:13 miod Exp $ + +MAN= cacheflush.3 +MANSUBDIR= sgi + +#.if ${MACHINE_ARCH} == "mips64" +#NOPIC= +#SRCS= +#.include <bsd.lib.mk> +#.else +NOPROG= +.include <bsd.prog.mk> +#.endif diff --git a/lib/libarch/mips64/cacheflush.3 b/lib/libarch/mips64/cacheflush.3 new file mode 100644 index 00000000000..6346b83fd1e --- /dev/null +++ b/lib/libarch/mips64/cacheflush.3 @@ -0,0 +1,81 @@ +.\" $OpenBSD: cacheflush.3,v 1.1 2009/09/27 18:20:13 miod Exp $ +.\" +.\" Copyright (c) 2009 Miodrag Vallat. +.\" +.\" Permission to use, copy, modify, and distribute this software for any +.\" purpose with or without fee is hereby granted, provided that the above +.\" copyright notice and this permission notice appear in all copies. +.\" +.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.\" +.Dd $Mdocdate: September 27 2009 $ +.Dt CACHEFLUSH 3 +.Os +.Sh NAME +.Nm cacheflush , +.Nm _flush_cache +.Nd CPU cache synchronization functions +.Sh SYNOPSIS +.In machine/sysarch.h +.Ft int +.Fn cacheflush "void *addr" "int nbytes" "int cache" +.Ft int +.Fn _flush_cache "char *addr" "int nbytes" "int cache" +.Sh DESCRIPTION +.Fn cacheflush +allows a process to synchronize the contents of the processor caches with +main memory. +Since MIPS processors have separate instruction and data caches, this +function allows for dynamically generated code to run correctly. +.Pp +.Nm +operates on a contiguous memory range in the current process address space, +starting at address +.Fa addr +and +.Fa nbytes +bytes long. +The caches to be synchronized are specified in the +.Fa cache +argument with one of the following values: +.Pp +.Bl -tag -width "ICACHEXXX" -compact -offset ind +.It Dv ICACHE +synchronize the instruction cache +.It Dv DCACHE +synchronize the data cache +.It Dv BCACHE +synchronize both the instruction and data caches +.El +.Pp +.Nm _flush_cache +is an alias for the +.Nm cacheflush +function. +.Sh RETURN VALUES +Upon successful completion, +.Nm +returns zero. +Otherwise, a value of \-1 is returned and +.Va errno +is set to indicate the error. +.Sh ERRORS +.Nm +will fail if: +.Bl -tag -width Er +.It Bq Er EFAULT +The address range specified by +.Fa addr +and +.Fa nbytes +is not part of the process allocated address space. +.It Bq Er EINVAL +.Fa cache +is not valid. +.El diff --git a/lib/libc/arch/mips64/gen/Makefile.inc b/lib/libc/arch/mips64/gen/Makefile.inc index 2e12b8d105f..d1e0a54c66d 100644 --- a/lib/libc/arch/mips64/gen/Makefile.inc +++ b/lib/libc/arch/mips64/gen/Makefile.inc @@ -1,9 +1,10 @@ -# $OpenBSD: Makefile.inc,v 1.7 2008/12/09 19:52:33 martynas Exp $ +# $OpenBSD: Makefile.inc,v 1.8 2009/09/27 18:20:13 miod Exp $ SRCS+= _setjmp.S fabs.S infinity.c ldexp.S modf.S nan.c SRCS+= flt_rounds.c fpgetmask.c fpgetround.c fpgetsticky.c fpsetmask.c \ fpsetround.c fpsetsticky.c SRCS+= fpclassifyl.c isfinitel.c isinfl.c isnanl.c isnormall.c signbitl.c SRCS+= setjmp.S sigsetjmp.S +SRCS+= cacheflush.c SRCS+= alloca.c diff --git a/lib/libc/arch/mips64/gen/cacheflush.c b/lib/libc/arch/mips64/gen/cacheflush.c new file mode 100644 index 00000000000..17291fe8d73 --- /dev/null +++ b/lib/libc/arch/mips64/gen/cacheflush.c @@ -0,0 +1,37 @@ +/* $OpenBSD: cacheflush.c,v 1.1 2009/09/27 18:20:13 miod Exp $ */ + +/* + * Copyright (c) 2009 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * IRIX-compatible cacheflush() and _flush_cache() functions + */ + +#include <sys/types.h> +#include <machine/sysarch.h> + +int +cacheflush(void *addr, int nbytes, int cache) +{ + struct mips64_cacheflush_args args; + + args.va = (vaddr_t)addr; + args.sz = (size_t)nbytes; + args.which = cache; + return sysarch(MIPS64_CACHEFLUSH, (void *)&args); +} + +__weak_alias(_flush_cache, cacheflush); diff --git a/sys/arch/mips64/include/sysarch.h b/sys/arch/mips64/include/sysarch.h new file mode 100644 index 00000000000..623d7191fca --- /dev/null +++ b/sys/arch/mips64/include/sysarch.h @@ -0,0 +1,50 @@ +/* $OpenBSD: sysarch.h,v 1.1 2009/09/27 18:20:13 miod Exp $ */ + +/* + * Copyright (c) 2009 Miodrag Vallat. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _MIPS64_SYSARCH_H_ +#define _MIPS64_SYSARCH_H_ + +/* + * Architecture specific syscalls (mips64) + */ + +#define MIPS64_CACHEFLUSH 0 + +/* + * Argument structure and defines to mimic IRIX cacheflush() system call + */ + +struct mips64_cacheflush_args { + vaddr_t va; + size_t sz; + int which; +#define ICACHE 0x01 +#define DCACHE 0x02 +#define BCACHE (ICACHE | DCACHE) +}; + +#ifndef _KERNEL +#include <sys/cdefs.h> +__BEGIN_DECLS +int cacheflush(void *, int, int); +int _flush_cache(char *, int, int); +int sysarch(int, void *); +__END_DECLS +#endif /* _KERNEL */ + +#endif /* _MIPS64_SYSARCH_H_ */ diff --git a/sys/arch/mips64/mips64/sys_machdep.c b/sys/arch/mips64/mips64/sys_machdep.c index c3c71dbeaa8..e492c10e565 100644 --- a/sys/arch/mips64/mips64/sys_machdep.c +++ b/sys/arch/mips64/mips64/sys_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: sys_machdep.c,v 1.2 2005/08/01 15:43:12 miod Exp $ */ +/* $OpenBSD: sys_machdep.c,v 1.3 2009/09/27 18:20:13 miod Exp $ */ /* * Copyright (c) 1992, 1993 @@ -50,6 +50,14 @@ #include <sys/mount.h> #include <sys/syscallargs.h> +#include <uvm/uvm.h> + +#include <mips64/sysarch.h> + +#include <machine/autoconf.h> + +int mips64_cacheflush(struct proc *, struct mips64_cacheflush_args *); + int sys_sysarch(p, v, retval) struct proc *p; @@ -63,9 +71,75 @@ sys_sysarch(p, v, retval) int error = 0; switch(SCARG(uap, op)) { + case MIPS64_CACHEFLUSH: + { + struct mips64_cacheflush_args cfa; + + if ((error = copyin(SCARG(uap, parms), &cfa, sizeof cfa)) != 0) + return error; + error = mips64_cacheflush(p, &cfa); + } + break; default: error = EINVAL; break; } - return(error); + + return error; +} + +int +mips64_cacheflush(struct proc *p, struct mips64_cacheflush_args *cfa) +{ + vaddr_t va; + paddr_t pa; + size_t sz, chunk; + struct vm_map *map = &p->p_vmspace->vm_map; + struct pmap *pm = map->pmap; + struct vm_map_entry *entry; + int rc = 0; + + /* + * Sanity checks. + */ + if ((cfa->which & BCACHE) != cfa->which) + return EINVAL; + + if (cfa->which == 0) + return 0; + + va = cfa->va; + sz = cfa->sz; + chunk = PAGE_SIZE - (va & PAGE_MASK); + vm_map_lock_read(map); + if (va < vm_map_min(map) || va + sz > vm_map_max(map) || va + sz < va) + rc = EFAULT; + else while (sz != 0) { + if (chunk > sz) + chunk = sz; + + /* + * Check for a resident mapping first, this is faster than + * uvm_map_lookup_entry(). + */ + if (pmap_extract(pm, va, &pa) != 0) { + if (cfa->which & ICACHE) + Mips_InvalidateICache(va, chunk); + if (cfa->which & DCACHE) + Mips_HitSyncDCache(va, chunk); + } else { + if (uvm_map_lookup_entry(map, va, &entry) == FALSE) { + rc = EFAULT; + break; + } + /* else simply not resident at the moment */ + } + + va += chunk; + sz -= chunk; + chunk = PAGE_SIZE; + } + vm_map_unlock_read(map); + + return rc; } diff --git a/sys/arch/sgi/include/sysarch.h b/sys/arch/sgi/include/sysarch.h new file mode 100644 index 00000000000..b7c783f2c72 --- /dev/null +++ b/sys/arch/sgi/include/sysarch.h @@ -0,0 +1,3 @@ +/* $OpenBSD: sysarch.h,v 1.1 2009/09/27 18:20:13 miod Exp $ */ +/* public domain */ +#include <mips64/sysarch.h> |