1/*	$NetBSD: csan.h,v 1.2 2019/11/06 06:57:22 maxv Exp $	*/
  2
  3/*
  4 * Copyright (c) 2019 The NetBSD Foundation, Inc.
  5 * All rights reserved.
  6 *
  7 * This code is derived from software contributed to The NetBSD Foundation
  8 * by Maxime Villard.
  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#include <machine/cpufunc.h>
 33#include <machine/stack.h>
 34#include <machine/vmparam.h>
 35
 36static inline bool
 37kcsan_md_unsupported(vm_offset_t addr)
 38{
 39	return false;
 40}
 41
 42static inline bool
 43kcsan_md_is_avail(void)
 44{
 45	return true;
 46}
 47
 48static inline void
 49kcsan_md_disable_intrs(uint64_t *state)
 50{
 51
 52	*state = intr_disable();
 53}
 54
 55static inline void
 56kcsan_md_enable_intrs(uint64_t *state)
 57{
 58
 59	intr_restore(*state);
 60}
 61
 62static inline void
 63kcsan_md_delay(uint64_t us)
 64{
 65	DELAY(us);
 66}
 67
 68static void
 69kcsan_md_unwind(void)
 70{
 71#ifdef DDB
 72	c_db_sym_t sym;
 73	db_expr_t offset;
 74	const char *symname;
 75#endif
 76	struct unwind_state frame;
 77	int nsym;
 78
 79	frame.fp = (uintptr_t)__builtin_frame_address(0);
 80	frame.pc = (uintptr_t)kcsan_md_unwind;
 81	nsym = 0;
 82
 83	while (1) {
 84		if (!unwind_frame(curthread, &frame))
 85			break;
 86		if (!INKERNEL((vm_offset_t)frame.pc))
 87			break;
 88
 89#ifdef DDB
 90		sym = db_search_symbol((vm_offset_t)frame.pc, DB_STGY_PROC,
 91		    &offset);
 92		db_symbol_values(sym, &symname, NULL);
 93		printf("#%d %p in %s+%#lx\n", nsym, (void *)frame.pc,
 94		    symname, offset);
 95#else
 96		printf("#%d %p\n", nsym, (void *)frame.pc);
 97#endif
 98		nsym++;
 99
100		if (nsym >= 15) {
101			break;
102		}
103	}
104}