| 1 | /*- |
| 2 | * SPDX-License-Identifier: BSD-3-Clause |
| 3 | * |
| 4 | * Copyright (c) 1982, 1988, 1991, 1993 |
| 5 | *	The Regents of the University of California. All rights reserved. |
| 6 | * (c) UNIX System Laboratories, Inc. |
| 7 | * All or some portions of this file are derived from material licensed |
| 8 | * to the University of California by American Telephone and Telegraph |
| 9 | * Co. or Unix System Laboratories, Inc. and are reproduced herein with |
| 10 | * the permission of UNIX System Laboratories, Inc. |
| 11 | * |
| 12 | * Redistribution and use in source and binary forms, with or without |
| 13 | * modification, are permitted provided that the following conditions |
| 14 | * are met: |
| 15 | * 1. Redistributions of source code must retain the above copyright |
| 16 | * notice, this list of conditions and the following disclaimer. |
| 17 | * 2. Redistributions in binary form must reproduce the above copyright |
| 18 | * notice, this list of conditions and the following disclaimer in the |
| 19 | * documentation and/or other materials provided with the distribution. |
| 20 | * 3. Neither the name of the University nor the names of its contributors |
| 21 | * may be used to endorse or promote products derived from this software |
| 22 | * without specific prior written permission. |
| 23 | * |
| 24 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
| 25 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| 26 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
| 27 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
| 28 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
| 29 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
| 30 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
| 31 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
| 32 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
| 33 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
| 34 | * SUCH DAMAGE. |
| 35 | */ |
| 36 | |
| 37 | #ifndef _SYS_SYSTM_H_ |
| 38 | #define	_SYS_SYSTM_H_ |
| 39 | |
| 40 | #include <sys/types.h> |
| 41 | #include <sys/callout.h> |
| 42 | #include <sys/kassert.h> |
| 43 | #include <sys/queue.h> |
| 44 | #include <sys/stdint.h>		/* for people using printf mainly */ |
| 45 | #include <machine/atomic.h> |
| 46 | #include <machine/cpufunc.h> |
| 47 | |
| 48 | __NULLABILITY_PRAGMA_PUSH |
| 49 | |
| 50 | #ifdef _KERNEL |
| 51 | extern int cold;		/* nonzero if we are doing a cold boot */ |
| 52 | extern int suspend_blocked;	/* block suspend due to pending shutdown */ |
| 53 | extern int rebooting;		/* kern_reboot() has been called. */ |
| 54 | extern const char version[];	/* system version */ |
| 55 | extern const char compiler_version[];	/* compiler version */ |
| 56 | extern const char copyright[];	/* system copyright */ |
| 57 | extern int kstack_pages;	/* number of kernel stack pages */ |
| 58 | |
| 59 | extern u_long pagesizes[];	/* supported page sizes */ |
| 60 | extern long physmem;		/* physical memory */ |
| 61 | extern long realmem;		/* 'real' memory */ |
| 62 | |
| 63 | extern char *rootdevnames[2];	/* names of possible root devices */ |
| 64 | |
| 65 | extern int boothowto;		/* reboot flags, from console subsystem */ |
| 66 | extern int bootverbose;		/* nonzero to print verbose messages */ |
| 67 | |
| 68 | extern int maxusers;		/* system tune hint */ |
| 69 | extern int ngroups_max;		/* max # of supplemental groups */ |
| 70 | extern int vm_guest;		/* Running as virtual machine guest? */ |
| 71 | |
| 72 | extern u_long maxphys;		/* max raw I/O transfer size */ |
| 73 | |
| 74 | /* |
| 75 | * Detected virtual machine guest types. The intention is to expand |
| 76 | * and/or add to the VM_GUEST_VM type if specific VM functionality is |
| 77 | * ever implemented (e.g. vendor-specific paravirtualization features). |
| 78 | * Keep in sync with vm_guest_sysctl_names[]. |
| 79 | */ |
| 80 | enum VM_GUEST { VM_GUEST_NO = 0, VM_GUEST_VM, VM_GUEST_XEN, VM_GUEST_HV, |
| 81 | 		VM_GUEST_VMWARE, VM_GUEST_KVM, VM_GUEST_BHYVE, VM_GUEST_VBOX, |
| 82 | 		VM_GUEST_PARALLELS, VM_GUEST_NVMM, VM_GUEST_LAST }; |
| 83 | |
| 84 | #endif /* KERNEL */ |
| 85 | |
| 86 | /* |
| 87 | * Align variables. |
| 88 | */ |
| 89 | #define	__read_mostly		__section(".data.read_mostly") |
| 90 | #define	__read_frequently	__section(".data.read_frequently") |
| 91 | #define	__exclusive_cache_line	__aligned(CACHE_LINE_SIZE) \ |
| 92 | 				 __section(".data.exclusive_cache_line") |
| 93 | #if defined(_STANDALONE) |
| 94 | struct ucred; |
| 95 | #endif |
| 96 | |
| 97 | #ifdef _KERNEL |
| 98 | #include <sys/param.h>		/* MAXCPU */ |
| 99 | #include <sys/pcpu.h>		/* curthread */ |
| 100 | #include <sys/kpilite.h> |
| 101 | |
| 102 | extern bool scheduler_stopped; |
| 103 | |
| 104 | /* |
| 105 | * If we have already panic'd and this is the thread that called |
| 106 | * panic(), then don't block on any mutexes but silently succeed. |
| 107 | * Otherwise, the kernel will deadlock since the scheduler isn't |
| 108 | * going to run the thread that holds any lock we need. |
| 109 | */ |
| 110 | #define	SCHEDULER_STOPPED()	__predict_false(scheduler_stopped) |
| 111 | |
| 112 | extern const int osreldate; |
| 113 | |
| 114 | extern const void *zero_region;	/* address space maps to a zeroed page	*/ |
| 115 | |
| 116 | extern int unmapped_buf_allowed; |
| 117 | |
| 118 | #ifdef __LP64__ |
| 119 | #define	IOSIZE_MAX		iosize_max() |
| 120 | #define	DEVFS_IOSIZE_MAX	devfs_iosize_max() |
| 121 | #else |
| 122 | #define	IOSIZE_MAX		SSIZE_MAX |
| 123 | #define	DEVFS_IOSIZE_MAX	SSIZE_MAX |
| 124 | #endif |
| 125 | |
| 126 | /* |
| 127 | * General function declarations. |
| 128 | */ |
| 129 | |
| 130 | struct inpcb; |
| 131 | struct lock_object; |
| 132 | struct malloc_type; |
| 133 | struct mtx; |
| 134 | struct proc; |
| 135 | struct socket; |
| 136 | struct thread; |
| 137 | struct tty; |
| 138 | struct ucred; |
| 139 | struct uio; |
| 140 | struct _jmp_buf; |
| 141 | struct trapframe; |
| 142 | struct eventtimer; |
| 143 | |
| 144 | int	setjmp(struct _jmp_buf *) __returns_twice; |
| 145 | void	longjmp(struct _jmp_buf *, int) __dead2; |
| 146 | int	dumpstatus(vm_offset_t addr, off_t count); |
| 147 | int	nullop(void); |
| 148 | int	eopnotsupp(void); |
| 149 | int	ureadc(int, struct uio *); |
| 150 | void	hashdestroy(void *, struct malloc_type *, u_long); |
| 151 | void	*hashinit(int count, struct malloc_type *type, u_long *hashmask); |
| 152 | void	*hashinit_flags(int count, struct malloc_type *type, |
| 153 | u_long *hashmask, int flags); |
| 154 | #define	HASH_NOWAIT	0x00000001 |
| 155 | #define	HASH_WAITOK	0x00000002 |
| 156 | |
| 157 | void	*phashinit(int count, struct malloc_type *type, u_long *nentries); |
| 158 | void	*phashinit_flags(int count, struct malloc_type *type, u_long *nentries, |
| 159 | int flags); |
| 160 | |
| 161 | void	cpu_flush_dcache(void *, size_t); |
| 162 | void	cpu_rootconf(void); |
| 163 | void	critical_enter_KBI(void); |
| 164 | void	critical_exit_KBI(void); |
| 165 | void	critical_exit_preempt(void); |
| 166 | void	init_param1(void); |
| 167 | void	init_param2(long physpages); |
| 168 | void	init_static_kenv(char *, size_t); |
| 169 | void	tablefull(const char *); |
| 170 | |
| 171 | /* |
| 172 | * Allocate per-thread "current" state in the linuxkpi |
| 173 | */ |
| 174 | extern int (*lkpi_alloc_current)(struct thread *, int); |
| 175 | int linux_alloc_current_noop(struct thread *, int); |
| 176 | |
| 177 | #if (defined(KLD_MODULE) && !defined(KLD_TIED)) || defined(KTR_CRITICAL) || !defined(_KERNEL) || defined(GENOFFSET) |
| 178 | #define critical_enter() critical_enter_KBI() |
| 179 | #define critical_exit() critical_exit_KBI() |
| 180 | #else |
| 181 | static __inline void |
| 182 | critical_enter(void) |
| 183 | { |
| 184 | 	struct thread_lite *td; |
| 185 | |
| 186 | 	td = (struct thread_lite *)curthread; |
| 187 | 	td->td_critnest++; |
| 188 | 	atomic_interrupt_fence(); |
| 189 | } |
| 190 | |
| 191 | static __inline void |
| 192 | critical_exit(void) |
| 193 | { |
| 194 | 	struct thread_lite *td; |
| 195 | |
| 196 | 	td = (struct thread_lite *)curthread; |
| 197 | 	KASSERT(td->td_critnest != 0, |
| 198 | 	 ("critical_exit: td_critnest == 0")); |
| 199 | 	atomic_interrupt_fence(); |
| 200 | 	td->td_critnest--; |
| 201 | 	atomic_interrupt_fence(); |
| 202 | 	if (__predict_false(td->td_owepreempt)) |
| 203 | 		critical_exit_preempt(); |
| 204 | |
| 205 | } |
| 206 | #endif |
| 207 | |
| 208 | #ifdef EARLY_PRINTF |
| 209 | typedef void early_putc_t(int ch); |
| 210 | extern early_putc_t *early_putc; |
| 211 | #define	CHECK_EARLY_PRINTF(x)	\ |
| 212 | __CONCAT(early_printf_, EARLY_PRINTF) == __CONCAT(early_printf_, x) |
| 213 | #define	early_printf_1		1 |
| 214 | #define	early_printf_mvebu	2 |
| 215 | #define	early_printf_ns8250	3 |
| 216 | #define	early_printf_pl011	4 |
| 217 | #define	early_printf_snps	5 |
| 218 | #define	early_printf_sbi	6 |
| 219 | #else |
| 220 | #define	CHECK_EARLY_PRINTF(x)	0 |
| 221 | #endif |
| 222 | int	kvprintf(char const *, void (*)(int, void*), void *, int, |
| 223 | 	 __va_list) __printflike(1, 0); |
| 224 | void	log(int, const char *, ...) __printflike(2, 3); |
| 225 | void	log_console(struct uio *); |
| 226 | void	vlog(int, const char *, __va_list) __printflike(2, 0); |
| 227 | int	asprintf(char **ret, struct malloc_type *mtp, const char *format, |
| 228 | 	 ...) __printflike(3, 4); |
| 229 | int	printf(const char *, ...) __printflike(1, 2); |
| 230 | int	snprintf(char *, size_t, const char *, ...) __printflike(3, 4); |
| 231 | int	sprintf(char *buf, const char *, ...) __printflike(2, 3); |
| 232 | int	uprintf(const char *, ...) __printflike(1, 2); |
| 233 | int	vprintf(const char *, __va_list) __printflike(1, 0); |
| 234 | int	vasprintf(char **ret, struct malloc_type *mtp, const char *format, |
| 235 | 	 __va_list ap) __printflike(3, 0); |
| 236 | int	vsnprintf(char *, size_t, const char *, __va_list) __printflike(3, 0); |
| 237 | int	vsnrprintf(char *, size_t, int, const char *, __va_list) __printflike(4, 0); |
| 238 | int	vsprintf(char *buf, const char *, __va_list) __printflike(2, 0); |
| 239 | int	sscanf(const char *, char const * _Nonnull, ...) __scanflike(2, 3); |
| 240 | int	vsscanf(const char * _Nonnull, char const * _Nonnull, __va_list) __scanflike(2, 0); |
| 241 | long	strtol(const char *, char **, int); |
| 242 | u_long	strtoul(const char *, char **, int); |
| 243 | quad_t	strtoq(const char *, char **, int); |
| 244 | u_quad_t strtouq(const char *, char **, int); |
| 245 | void	tprintf(struct proc *p, int pri, const char *, ...) __printflike(3, 4); |
| 246 | void	vtprintf(struct proc *, int, const char *, __va_list) __printflike(3, 0); |
| 247 | void	hexdump(const void *ptr, int length, const char *hdr, int flags); |
| 248 | #define	HD_COLUMN_MASK	0xff |
| 249 | #define	HD_DELIM_MASK	0xff00 |
| 250 | #define	HD_OMIT_COUNT	(1 << 16) |
| 251 | #define	HD_OMIT_HEX	(1 << 17) |
| 252 | #define	HD_OMIT_CHARS	(1 << 18) |
| 253 | |
| 254 | #define ovbcopy(f, t, l) bcopy((f), (t), (l)) |
| 255 | void	explicit_bzero(void * _Nonnull, size_t); |
| 256 | |
| 257 | void	*memset(void * _Nonnull buf, int c, size_t len); |
| 258 | void	*memcpy(void * _Nonnull to, const void * _Nonnull from, size_t len); |
| 259 | void	*memmove(void * _Nonnull dest, const void * _Nonnull src, size_t n); |
| 260 | int	memcmp(const void *b1, const void *b2, size_t len); |
| 261 | |
| 262 | #ifdef SAN_NEEDS_INTERCEPTORS |
| 263 | #define	SAN_INTERCEPTOR(func)	\ |
| 264 | 	__CONCAT(SAN_INTERCEPTOR_PREFIX, __CONCAT(_, func)) |
| 265 | void	*SAN_INTERCEPTOR(memset)(void *, int, size_t); |
| 266 | void	*SAN_INTERCEPTOR(memcpy)(void *, const void *, size_t); |
| 267 | void	*SAN_INTERCEPTOR(memmove)(void *, const void *, size_t); |
| 268 | int	SAN_INTERCEPTOR(memcmp)(const void *, const void *, size_t); |
| 269 | #ifndef SAN_RUNTIME |
| 270 | #define bcopy(from, to, len)	SAN_INTERCEPTOR(memmove)((to), (from), (len)) |
| 271 | #define bzero(buf, len)		SAN_INTERCEPTOR(memset)((buf), 0, (len)) |
| 272 | #define bcmp(b1, b2, len)	SAN_INTERCEPTOR(memcmp)((b1), (b2), (len)) |
| 273 | #define memset(buf, c, len)	SAN_INTERCEPTOR(memset)((buf), (c), (len)) |
| 274 | #define memcpy(to, from, len)	SAN_INTERCEPTOR(memcpy)((to), (from), (len)) |
| 275 | #define memmove(dest, src, n)	SAN_INTERCEPTOR(memmove)((dest), (src), (n)) |
| 276 | #define memcmp(b1, b2, len)	SAN_INTERCEPTOR(memcmp)((b1), (b2), (len)) |
| 277 | #endif /* !SAN_RUNTIME */ |
| 278 | #else /* !SAN_NEEDS_INTERCEPTORS */ |
| 279 | #define bcopy(from, to, len)	__builtin_memmove((to), (from), (len)) |
| 280 | #define bzero(buf, len)		__builtin_memset((buf), 0, (len)) |
| 281 | #define bcmp(b1, b2, len)	__builtin_memcmp((b1), (b2), (len)) |
| 282 | #define memset(buf, c, len)	__builtin_memset((buf), (c), (len)) |
| 283 | #define memcpy(to, from, len)	__builtin_memcpy((to), (from), (len)) |
| 284 | #define memmove(dest, src, n)	__builtin_memmove((dest), (src), (n)) |
| 285 | #define memcmp(b1, b2, len)	__builtin_memcmp((b1), (b2), (len)) |
| 286 | #endif /* SAN_NEEDS_INTERCEPTORS */ |
| 287 | |
| 288 | void	*memset_early(void * _Nonnull buf, int c, size_t len); |
| 289 | #define bzero_early(buf, len) memset_early((buf), 0, (len)) |
| 290 | void	*memcpy_early(void * _Nonnull to, const void * _Nonnull from, size_t len); |
| 291 | void	*memmove_early(void * _Nonnull dest, const void * _Nonnull src, size_t n); |
| 292 | #define bcopy_early(from, to, len) memmove_early((to), (from), (len)) |
| 293 | |
| 294 | #define	copystr(src, dst, len, outlen)	({			\ |
| 295 | 	size_t __r, __len, *__outlen;				\ |
| 296 | 								\ |
| 297 | 	__len = (len);						\ |
| 298 | 	__outlen = (outlen);					\ |
| 299 | 	__r = strlcpy((dst), (src), __len);			\ |
| 300 | 	if (__outlen != NULL)					\ |
| 301 | 		*__outlen = ((__r >= __len) ? __len : __r + 1);	\ |
| 302 | 	((__r >= __len) ? ENAMETOOLONG : 0);			\ |
| 303 | }) |
| 304 | |
| 305 | int __result_use_check copyinstr(const void * __restrict udaddr, |
| 306 | void * _Nonnull __restrict kaddr, size_t len, |
| 307 | size_t * __restrict lencopied); |
| 308 | int __result_use_check copyin(const void * __restrict udaddr, |
| 309 | void * _Nonnull __restrict kaddr, size_t len); |
| 310 | int __result_use_check copyin_nofault(const void * __restrict udaddr, |
| 311 | void * _Nonnull __restrict kaddr, size_t len); |
| 312 | __nodiscard int copyout(const void * _Nonnull __restrict kaddr, |
| 313 | void * __restrict udaddr, size_t len); |
| 314 | __nodiscard int copyout_nofault( |
| 315 | const void * _Nonnull __restrict kaddr, void * __restrict udaddr, |
| 316 | size_t len); |
| 317 | |
| 318 | #ifdef SAN_NEEDS_INTERCEPTORS |
| 319 | int	SAN_INTERCEPTOR(copyin)(const void *, void *, size_t); |
| 320 | int	SAN_INTERCEPTOR(copyinstr)(const void *, void *, size_t, size_t *); |
| 321 | int	SAN_INTERCEPTOR(copyout)(const void *, void *, size_t); |
| 322 | #ifndef SAN_RUNTIME |
| 323 | #define	copyin(u, k, l)		SAN_INTERCEPTOR(copyin)((u), (k), (l)) |
| 324 | #define	copyinstr(u, k, l, lc)	SAN_INTERCEPTOR(copyinstr)((u), (k), (l), (lc)) |
| 325 | #define	copyout(k, u, l)	SAN_INTERCEPTOR(copyout)((k), (u), (l)) |
| 326 | #endif /* !SAN_RUNTIME */ |
| 327 | #endif /* SAN_NEEDS_INTERCEPTORS */ |
| 328 | |
| 329 | int	fubyte(volatile const void *base); |
| 330 | long	fuword(volatile const void *base); |
| 331 | int	fuword16(volatile const void *base); |
| 332 | int32_t	fuword32(volatile const void *base); |
| 333 | int64_t	fuword64(volatile const void *base); |
| 334 | int __result_use_check fueword(volatile const void *base, long *val); |
| 335 | int __result_use_check fueword32(volatile const void *base, int32_t *val); |
| 336 | int __result_use_check fueword64(volatile const void *base, int64_t *val); |
| 337 | __nodiscard int subyte(volatile void *base, int byte); |
| 338 | __nodiscard int suword(volatile void *base, long word); |
| 339 | __nodiscard int suword16(volatile void *base, int word); |
| 340 | __nodiscard int suword32(volatile void *base, int32_t word); |
| 341 | __nodiscard int suword64(volatile void *base, int64_t word); |
| 342 | uint32_t casuword32(volatile uint32_t *base, uint32_t oldval, uint32_t newval); |
| 343 | u_long	casuword(volatile u_long *p, u_long oldval, u_long newval); |
| 344 | int	casueword32(volatile uint32_t *base, uint32_t oldval, uint32_t *oldvalp, |
| 345 | 	 uint32_t newval); |
| 346 | int	casueword(volatile u_long *p, u_long oldval, u_long *oldvalp, |
| 347 | 	 u_long newval); |
| 348 | |
| 349 | #if defined(SAN_NEEDS_INTERCEPTORS) && !defined(KCSAN) |
| 350 | int	SAN_INTERCEPTOR(fubyte)(volatile const void *base); |
| 351 | int	SAN_INTERCEPTOR(fuword16)(volatile const void *base); |
| 352 | int	SAN_INTERCEPTOR(fueword)(volatile const void *base, long *val); |
| 353 | int	SAN_INTERCEPTOR(fueword32)(volatile const void *base, int32_t *val); |
| 354 | int	SAN_INTERCEPTOR(fueword64)(volatile const void *base, int64_t *val); |
| 355 | int	SAN_INTERCEPTOR(subyte)(volatile void *base, int byte); |
| 356 | int	SAN_INTERCEPTOR(suword)(volatile void *base, long word); |
| 357 | int	SAN_INTERCEPTOR(suword16)(volatile void *base, int word); |
| 358 | int	SAN_INTERCEPTOR(suword32)(volatile void *base, int32_t word); |
| 359 | int	SAN_INTERCEPTOR(suword64)(volatile void *base, int64_t word); |
| 360 | int	SAN_INTERCEPTOR(casueword32)(volatile uint32_t *base, uint32_t oldval, |
| 361 | 	 uint32_t *oldvalp, uint32_t newval); |
| 362 | int	SAN_INTERCEPTOR(casueword)(volatile u_long *p, u_long oldval, |
| 363 | 	 u_long *oldvalp, u_long newval); |
| 364 | #ifndef SAN_RUNTIME |
| 365 | #define	fubyte(b)		SAN_INTERCEPTOR(fubyte)((b)) |
| 366 | #define	fuword16(b)		SAN_INTERCEPTOR(fuword16)((b)) |
| 367 | #define	fueword(b, v)		SAN_INTERCEPTOR(fueword)((b), (v)) |
| 368 | #define	fueword32(b, v)		SAN_INTERCEPTOR(fueword32)((b), (v)) |
| 369 | #define	fueword64(b, v)		SAN_INTERCEPTOR(fueword64)((b), (v)) |
| 370 | #define	subyte(b, w)		SAN_INTERCEPTOR(subyte)((b), (w)) |
| 371 | #define	suword(b, w)		SAN_INTERCEPTOR(suword)((b), (w)) |
| 372 | #define	suword16(b, w)		SAN_INTERCEPTOR(suword16)((b), (w)) |
| 373 | #define	suword32(b, w)		SAN_INTERCEPTOR(suword32)((b), (w)) |
| 374 | #define	suword64(b, w)		SAN_INTERCEPTOR(suword64)((b), (w)) |
| 375 | #define	casueword32(b, o, p, n)	SAN_INTERCEPTOR(casueword32)((b), (o), (p), (n)) |
| 376 | #define	casueword(b, o, p, n)	SAN_INTERCEPTOR(casueword)((b), (o), (p), (n)) |
| 377 | #endif /* !SAN_RUNTIME */ |
| 378 | #endif /* SAN_NEEDS_INTERCEPTORS && !KCSAN */ |
| 379 | |
| 380 | int	sysbeep(int hertz, sbintime_t duration); |
| 381 | |
| 382 | void	hardclock(int cnt, int usermode); |
| 383 | void	hardclock_sync(int cpu); |
| 384 | void	statclock(int cnt, int usermode); |
| 385 | void	profclock(int cnt, int usermode, uintfptr_t pc); |
| 386 | |
| 387 | int	hardclockintr(void); |
| 388 | |
| 389 | void	startprofclock(struct proc *); |
| 390 | void	stopprofclock(struct proc *); |
| 391 | void	cpu_startprofclock(void); |
| 392 | void	cpu_stopprofclock(void); |
| 393 | void	suspendclock(void); |
| 394 | void	resumeclock(void); |
| 395 | sbintime_t 	cpu_idleclock(void); |
| 396 | void	cpu_activeclock(void); |
| 397 | void	cpu_new_callout(int cpu, sbintime_t bt, sbintime_t bt_opt); |
| 398 | void	cpu_et_frequency(struct eventtimer *et, uint64_t newfreq); |
| 399 | extern int	cpu_disable_c2_sleep; |
| 400 | extern int	cpu_disable_c3_sleep; |
| 401 | |
| 402 | extern void	(*tcp_hpts_softclock)(void); |
| 403 | extern volatile uint32_t __read_frequently hpts_that_need_softclock; |
| 404 | |
| 405 | #define	tcp_hpts_softclock()	do {					\ |
| 406 | 		if (hpts_that_need_softclock > 0)			\ |
| 407 | 			tcp_hpts_softclock();				\ |
| 408 | } while (0) |
| 409 | |
| 410 | char	*kern_getenv(const char *name); |
| 411 | void	freeenv(char *env); |
| 412 | int	getenv_int(const char *name, int *data); |
| 413 | int	getenv_uint(const char *name, unsigned int *data); |
| 414 | int	getenv_long(const char *name, long *data); |
| 415 | int	getenv_ulong(const char *name, unsigned long *data); |
| 416 | int	getenv_string(const char *name, char *data, int size); |
| 417 | int	getenv_int64(const char *name, int64_t *data); |
| 418 | int	getenv_uint64(const char *name, uint64_t *data); |
| 419 | int	getenv_quad(const char *name, quad_t *data); |
| 420 | int	getenv_bool(const char *name, bool *data); |
| 421 | bool	getenv_is_true(const char *name); |
| 422 | bool	getenv_is_false(const char *name); |
| 423 | int	kern_setenv(const char *name, const char *value); |
| 424 | int	kern_unsetenv(const char *name); |
| 425 | int	testenv(const char *name); |
| 426 | |
| 427 | int	getenv_array(const char *name, void *data, int size, int *psize, |
| 428 | int type_size, bool allow_signed); |
| 429 | #define	GETENV_UNSIGNED	false	/* negative numbers not allowed */ |
| 430 | #define	GETENV_SIGNED	true	/* negative numbers allowed */ |
| 431 | |
| 432 | typedef uint64_t (cpu_tick_f)(void); |
| 433 | void set_cputicker(cpu_tick_f *func, uint64_t freq, bool isvariable); |
| 434 | extern cpu_tick_f *cpu_ticks; |
| 435 | uint64_t cpu_tickrate(void); |
| 436 | uint64_t cputick2usec(uint64_t tick); |
| 437 | |
| 438 | #include <sys/libkern.h> |
| 439 | |
| 440 | /* Initialize the world */ |
| 441 | void	consinit(void); |
| 442 | void	cpu_initclocks(void); |
| 443 | void	cpu_initclocks_bsp(void); |
| 444 | void	cpu_initclocks_ap(void); |
| 445 | void	usrinfoinit(void); |
| 446 | |
| 447 | /* Finalize the world */ |
| 448 | void	kern_reboot(int) __dead2; |
| 449 | void	shutdown_nice(int); |
| 450 | |
| 451 | /* Stubs for obsolete functions that used to be for interrupt management */ |
| 452 | static __inline intrmask_t	splhigh(void)		{ return 0; } |
| 453 | static __inline intrmask_t	splimp(void)		{ return 0; } |
| 454 | static __inline intrmask_t	splnet(void)		{ return 0; } |
| 455 | static __inline intrmask_t	spltty(void)		{ return 0; } |
| 456 | static __inline void		splx(intrmask_t ipl __unused)	{ return; } |
| 457 | |
| 458 | /* |
| 459 | * Common `proc' functions are declared here so that proc.h can be included |
| 460 | * less often. |
| 461 | */ |
| 462 | int	_sleep(const void * _Nonnull chan, struct lock_object *lock, int pri, |
| 463 | 	 const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags); |
| 464 | #define	msleep(chan, mtx, pri, wmesg, timo)				\ |
| 465 | 	_sleep((chan), &(mtx)->lock_object, (pri), (wmesg),		\ |
| 466 | 	 tick_sbt * (timo), 0, C_HARDCLOCK) |
| 467 | #define	msleep_sbt(chan, mtx, pri, wmesg, bt, pr, flags)		\ |
| 468 | 	_sleep((chan), &(mtx)->lock_object, (pri), (wmesg), (bt), (pr),	\ |
| 469 | 	 (flags)) |
| 470 | int	msleep_spin_sbt(const void * _Nonnull chan, struct mtx *mtx, |
| 471 | 	 const char *wmesg, sbintime_t sbt, sbintime_t pr, int flags); |
| 472 | #define	msleep_spin(chan, mtx, wmesg, timo)				\ |
| 473 | 	msleep_spin_sbt((chan), (mtx), (wmesg), tick_sbt * (timo),	\ |
| 474 | 	 0, C_HARDCLOCK) |
| 475 | int	pause_sbt(const char *wmesg, sbintime_t sbt, sbintime_t pr, |
| 476 | 	 int flags); |
| 477 | static __inline int |
| 478 | pause(const char *wmesg, int timo) |
| 479 | { |
| 480 | 	return (pause_sbt(wmesg, tick_sbt * timo, 0, C_HARDCLOCK)); |
| 481 | } |
| 482 | #define	pause_sig(wmesg, timo)						\ |
| 483 | 	pause_sbt((wmesg), tick_sbt * (timo), 0, C_HARDCLOCK | C_CATCH) |
| 484 | #define	tsleep(chan, pri, wmesg, timo)					\ |
| 485 | 	_sleep((chan), NULL, (pri), (wmesg), tick_sbt * (timo),		\ |
| 486 | 	 0, C_HARDCLOCK) |
| 487 | #define	tsleep_sbt(chan, pri, wmesg, bt, pr, flags)			\ |
| 488 | 	_sleep((chan), NULL, (pri), (wmesg), (bt), (pr), (flags)) |
| 489 | void	wakeup(const void *chan); |
| 490 | void	wakeup_one(const void *chan); |
| 491 | void	wakeup_any(const void *chan); |
| 492 | |
| 493 | /* |
| 494 | * Common `struct cdev *' stuff are declared here to avoid #include poisoning |
| 495 | */ |
| 496 | |
| 497 | struct cdev; |
| 498 | dev_t dev2udev(struct cdev *x); |
| 499 | const char *devtoname(struct cdev *cdev); |
| 500 | |
| 501 | #ifdef __LP64__ |
| 502 | size_t	devfs_iosize_max(void); |
| 503 | size_t	iosize_max(void); |
| 504 | #endif |
| 505 | |
| 506 | int poll_no_poll(int events); |
| 507 | |
| 508 | /* XXX: Should be void nanodelay(u_int nsec); */ |
| 509 | void	DELAY(int usec); |
| 510 | |
| 511 | int kcmp_cmp(uintptr_t a, uintptr_t b); |
| 512 | |
| 513 | /* Root mount holdback API */ |
| 514 | struct root_hold_token { |
| 515 | 	int				flags; |
| 516 | 	const char			*who; |
| 517 | 	TAILQ_ENTRY(root_hold_token)	list; |
| 518 | }; |
| 519 | |
| 520 | struct root_hold_token *root_mount_hold(const char *identifier); |
| 521 | void root_mount_hold_token(const char *identifier, struct root_hold_token *h); |
| 522 | void root_mount_rel(struct root_hold_token *h); |
| 523 | int root_mounted(void); |
| 524 | |
| 525 | /* |
| 526 | * Unit number allocation API. (kern/subr_unit.c) |
| 527 | */ |
| 528 | struct unrhdr; |
| 529 | #define	UNR_NO_MTX	((void *)(uintptr_t)-1) |
| 530 | struct unrhdr *new_unrhdr(int low, int high, struct mtx *mutex); |
| 531 | void init_unrhdr(struct unrhdr *uh, int low, int high, struct mtx *mutex); |
| 532 | void delete_unrhdr(struct unrhdr *uh); |
| 533 | void clear_unrhdr(struct unrhdr *uh); |
| 534 | void clean_unrhdr(struct unrhdr *uh); |
| 535 | void clean_unrhdrl(struct unrhdr *uh); |
| 536 | int alloc_unr(struct unrhdr *uh); |
| 537 | int alloc_unr_specific(struct unrhdr *uh, u_int item); |
| 538 | int alloc_unrl(struct unrhdr *uh); |
| 539 | void free_unr(struct unrhdr *uh, u_int item); |
| 540 | void *create_iter_unr(struct unrhdr *uh); |
| 541 | int next_iter_unr(void *handle); |
| 542 | void free_iter_unr(void *handle); |
| 543 | |
| 544 | struct unrhdr64 { |
| 545 | uint64_t	counter; |
| 546 | }; |
| 547 | |
| 548 | static __inline void |
| 549 | new_unrhdr64(struct unrhdr64 *unr64, uint64_t low) |
| 550 | { |
| 551 | |
| 552 | 	unr64->counter = low; |
| 553 | } |
| 554 | |
| 555 | static __inline uint64_t |
| 556 | alloc_unr64(struct unrhdr64 *unr64) |
| 557 | { |
| 558 | |
| 559 | 	return (atomic_fetchadd_64(&unr64->counter, 1)); |
| 560 | } |
| 561 | |
| 562 | void	intr_prof_stack_use(struct thread *td, struct trapframe *frame); |
| 563 | |
| 564 | void counted_warning(unsigned *counter, const char *msg); |
| 565 | |
| 566 | /* |
| 567 | * APIs to manage deprecation and obsolescence. |
| 568 | */ |
| 569 | void _gone_in(int major, const char *msg, ...) __printflike(2, 3); |
| 570 | void _gone_in_dev(device_t dev, int major, const char *msg, ...) |
| 571 | __printflike(3, 4); |
| 572 | #ifdef NO_OBSOLETE_CODE |
| 573 | #define __gone_ok(m, msg)					 \ |
| 574 | 	_Static_assert(m < P_OSREL_MAJOR(__FreeBSD_version)),	 \ |
| 575 | 	 "Obsolete code: " msg) |
| 576 | #else |
| 577 | #define	__gone_ok(m, msg) |
| 578 | #endif |
| 579 | #define gone_in(major, msg, ...)	do {				\ |
| 580 | 	static bool __read_mostly __gone_in_ ## __LINE__ = true;	\ |
| 581 | 	__gone_ok(major, msg);						\ |
| 582 | 	if (__predict_false(__gone_in_ ## __LINE__)) {			\ |
| 583 | 		__gone_in_ ## __LINE__ = false;				\ |
| 584 | 		_gone_in(major, msg __VA_OPT__(,) __VA_ARGS__);		\ |
| 585 | 	}								\ |
| 586 | } while (0) |
| 587 | #define gone_in_dev(dev, major, msg, ...)	do {			\ |
| 588 | 	static bool __read_mostly __gone_in_ ## __LINE__ = true;	\ |
| 589 | 	__gone_ok(major, msg);						\ |
| 590 | 	if (__predict_false(__gone_in_ ## __LINE__)) {			\ |
| 591 | 		__gone_in_ ## __LINE__ = false;				\ |
| 592 | 		_gone_in_dev(dev, major, msg __VA_OPT__(,) __VA_ARGS__);\ |
| 593 | 	}								\ |
| 594 | } while (0) |
| 595 | |
| 596 | #ifdef INVARIANTS |
| 597 | #define	__diagused |
| 598 | #else |
| 599 | #define	__diagused	__unused |
| 600 | #endif |
| 601 | |
| 602 | #ifdef WITNESS |
| 603 | #define	__witness_used |
| 604 | #else |
| 605 | #define	__witness_used	__unused |
| 606 | #endif |
| 607 | |
| 608 | #endif /* _KERNEL */ |
| 609 | |
| 610 | __NULLABILITY_PRAGMA_POP |
| 611 | #endif /* !_SYS_SYSTM_H_ */ |