1/*	$NetBSD: ras.h,v 1.15 2021/01/11 21:51:20 skrll Exp $	*/
  2
  3/*-
  4 * Copyright (c) 2002, 2004, 2007 The NetBSD Foundation, Inc.
  5 * All rights reserved.
  6 *
  7 * This code is derived from software contributed to The NetBSD Foundation
  8 * by Gregory McGarry.
  9 *
 10 * Redistribution and use in source and binary forms, with or without
 11 * modification, are permitted provided that the following conditions
 12 * are met:
 13 * 1. Redistributions of source code must retain the above copyright
 14 *    notice, this list of conditions and the following disclaimer.
 15 * 2. Redistributions in binary form must reproduce the above copyright
 16 *    notice, this list of conditions and the following disclaimer in the
 17 *    documentation and/or other materials provided with the distribution.
 18 *
 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 22 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 29 * POSSIBILITY OF SUCH DAMAGE.
 30 */
 31
 32#ifndef _SYS_RAS_H_
 33#define _SYS_RAS_H_
 34
 35#ifndef __ASSEMBLER__
 36#include <sys/types.h>
 37#include <sys/queue.h>
 38
 39struct ras {
 40	struct ras	*ras_next;
 41	void		*ras_startaddr;
 42	void		*ras_endaddr;
 43};
 44
 45#define RAS_INSTALL		0
 46#define RAS_PURGE		1
 47#define RAS_PURGE_ALL		2
 48#else
 49#include <sys/cdefs.h>
 50#endif /* __ASSEMBLER__ */
 51
 52#ifdef _KERNEL
 53
 54#ifndef __ASSEMBLER__
 55struct proc;
 56
 57void	*ras_lookup(struct proc *, void *);
 58int	ras_fork(struct proc *, struct proc *);
 59int	ras_purgeall(void);
 60#endif /* __ASSEMBLER__ */
 61
 62#else /* !_KERNEL */
 63
 64#ifndef	RAS_DECL
 65
 66#define	RAS_DECL(name)							\
 67extern void __CONCAT(name,_ras_start(void)), __CONCAT(name,_ras_end(void))
 68
 69#endif	/* RAS_DECL */
 70
 71/*
 72 * RAS_START and RAS_END contain implicit instruction reordering
 73 * barriers.  See __insn_barrier() in <sys/cdefs.h>.
 74 *
 75 * Note: You are strongly advised to avoid coding RASs in C. There is a
 76 * good chance the compiler will generate code which cannot be restarted.
 77 */
 78#define	RAS_START(name)							\
 79	__asm volatile(".globl " ___STRING(name) "_ras_start\n"	\
 80			 ___STRING(name) "_ras_start:" 			\
 81	    ::: "memory")
 82
 83#define	RAS_END(name)							\
 84	__asm volatile(".globl " ___STRING(name) "_ras_end\n"		\
 85			 ___STRING(name) "_ras_end:"			\
 86	    ::: "memory")
 87
 88#define	RAS_ADDR(name)	((void *)(uintptr_t) __CONCAT(name,_ras_start))
 89#define	RAS_SIZE(name)	((size_t)((uintptr_t) __CONCAT(name,_ras_end) -	\
 90				  (uintptr_t) __CONCAT(name,_ras_start)))
 91
 92#ifndef __ASSEMBLER__
 93__BEGIN_DECLS
 94int rasctl(void *, size_t, int);
 95__END_DECLS
 96
 97#else /* __ASSEMBLER__ */
 98
 99#ifndef	_ASM_LS_CHAR
100#define	_ASM_LS_CHAR	;
101#endif
102
103/*
104 * RAS_START_ASM and RAS_END_ASM are for use within assembly code.
105 * This is the preferred method of coding a RAS.
106 */
107#define	RAS_START_ASM(name)						\
108	.globl _C_LABEL(__CONCAT(name,_ras_start))	 _ASM_LS_CHAR	\
109	_C_LABEL(__CONCAT(name,_ras_start)):
110
111#define	RAS_END_ASM(name)						\
112	.globl _C_LABEL(__CONCAT(name,_ras_end)) 	_ASM_LS_CHAR	\
113	_C_LABEL(__CONCAT(name,_ras_end)):
114
115/*
116 * RAS_START_ASM_HIDDEN and RAS_END_ASM_HIDDEN are similar to the above,
117 * except that they limit the scope of the symbol such that it will not
118 * be placed into the dynamic symbol table. Thus no other module (executable
119 * or shared library) can reference it directly.
120 */
121#define	RAS_START_ASM_HIDDEN(name)					\
122	.globl _C_LABEL(__CONCAT(name,_ras_start)) 	_ASM_LS_CHAR	\
123	.hidden _C_LABEL(__CONCAT(name,_ras_start)) 	_ASM_LS_CHAR	\
124	_C_LABEL(__CONCAT(name,_ras_start)):
125
126#define	RAS_END_ASM_HIDDEN(name)					\
127	.globl _C_LABEL(__CONCAT(name,_ras_end)) 	_ASM_LS_CHAR	\
128	.hidden _C_LABEL(__CONCAT(name,_ras_end)) 	_ASM_LS_CHAR	\
129	_C_LABEL(__CONCAT(name,_ras_end)):
130#endif /* __ASSEMBLER__ */
131
132#endif /* _KERNEL */
133
134#endif /* !_SYS_RAS_H_ */