12434137fSDmitry Chagin /*-
24d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause
32434137fSDmitry Chagin *
42434137fSDmitry Chagin * Copyright (c) 1994-1996 Søren Schmidt
52434137fSDmitry Chagin * All rights reserved.
62434137fSDmitry Chagin *
72434137fSDmitry Chagin * Redistribution and use in source and binary forms, with or without
82434137fSDmitry Chagin * modification, are permitted provided that the following conditions
92434137fSDmitry Chagin * are met:
102434137fSDmitry Chagin * 1. Redistributions of source code must retain the above copyright
112434137fSDmitry Chagin * notice, this list of conditions and the following disclaimer.
122434137fSDmitry Chagin * 2. Redistributions in binary form must reproduce the above copyright
132434137fSDmitry Chagin * notice, this list of conditions and the following disclaimer in the
142434137fSDmitry Chagin * documentation and/or other materials provided with the distribution.
152434137fSDmitry Chagin *
162434137fSDmitry Chagin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
172434137fSDmitry Chagin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
182434137fSDmitry Chagin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
192434137fSDmitry Chagin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
202434137fSDmitry Chagin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
212434137fSDmitry Chagin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
222434137fSDmitry Chagin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
232434137fSDmitry Chagin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
242434137fSDmitry Chagin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
252434137fSDmitry Chagin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
262434137fSDmitry Chagin * SUCH DAMAGE.
272434137fSDmitry Chagin */
282434137fSDmitry Chagin
292434137fSDmitry Chagin #include <sys/param.h>
302434137fSDmitry Chagin #include <sys/signal.h>
31*4281dab8SDmitry Chagin #include <x86/specialreg.h>
322434137fSDmitry Chagin #include <x86/trap.h>
33*4281dab8SDmitry Chagin #include <x86/x86_var.h>
342434137fSDmitry Chagin
352434137fSDmitry Chagin #include <x86/linux/linux_x86.h>
362434137fSDmitry Chagin
379016ec05SDmitry Chagin #define LINUX_T_UNKNOWN 255
389016ec05SDmitry Chagin static int _bsd_to_linux_trapcode[] = {
399016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 0 */
409016ec05SDmitry Chagin 6, /* 1 T_PRIVINFLT */
419016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 2 */
429016ec05SDmitry Chagin 3, /* 3 T_BPTFLT */
439016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 4 */
449016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 5 */
459016ec05SDmitry Chagin 16, /* 6 T_ARITHTRAP */
469016ec05SDmitry Chagin 254, /* 7 T_ASTFLT */
479016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 8 */
489016ec05SDmitry Chagin 13, /* 9 T_PROTFLT */
499016ec05SDmitry Chagin 1, /* 10 T_TRCTRAP */
509016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 11 */
519016ec05SDmitry Chagin 14, /* 12 T_PAGEFLT */
529016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 13 */
539016ec05SDmitry Chagin 17, /* 14 T_ALIGNFLT */
549016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 15 */
559016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 16 */
569016ec05SDmitry Chagin LINUX_T_UNKNOWN, /* 17 */
579016ec05SDmitry Chagin 0, /* 18 T_DIVIDE */
589016ec05SDmitry Chagin 2, /* 19 T_NMI */
599016ec05SDmitry Chagin 4, /* 20 T_OFLOW */
609016ec05SDmitry Chagin 5, /* 21 T_BOUND */
619016ec05SDmitry Chagin 7, /* 22 T_DNA */
629016ec05SDmitry Chagin 8, /* 23 T_DOUBLEFLT */
639016ec05SDmitry Chagin 9, /* 24 T_FPOPFLT */
649016ec05SDmitry Chagin 10, /* 25 T_TSSFLT */
659016ec05SDmitry Chagin 11, /* 26 T_SEGNPFLT */
669016ec05SDmitry Chagin 12, /* 27 T_STKFLT */
679016ec05SDmitry Chagin 18, /* 28 T_MCHK */
689016ec05SDmitry Chagin 19, /* 29 T_XMMFLT */
699016ec05SDmitry Chagin 15 /* 30 T_RESERVED */
709016ec05SDmitry Chagin };
719016ec05SDmitry Chagin
722434137fSDmitry Chagin /*
732434137fSDmitry Chagin * If FreeBSD & Linux have a difference of opinion about what a trap
742434137fSDmitry Chagin * means, deal with it here.
752434137fSDmitry Chagin */
762434137fSDmitry Chagin int
linux_translate_traps(int signal,int trap_code)772434137fSDmitry Chagin linux_translate_traps(int signal, int trap_code)
782434137fSDmitry Chagin {
792434137fSDmitry Chagin if (signal != SIGBUS)
802434137fSDmitry Chagin return (signal);
812434137fSDmitry Chagin switch (trap_code) {
822434137fSDmitry Chagin case T_PROTFLT:
832434137fSDmitry Chagin case T_TSSFLT:
842434137fSDmitry Chagin case T_DOUBLEFLT:
852434137fSDmitry Chagin case T_PAGEFLT:
862434137fSDmitry Chagin return (SIGSEGV);
872434137fSDmitry Chagin default:
882434137fSDmitry Chagin return (signal);
892434137fSDmitry Chagin }
902434137fSDmitry Chagin }
919016ec05SDmitry Chagin
929016ec05SDmitry Chagin int
bsd_to_linux_trapcode(int code)939016ec05SDmitry Chagin bsd_to_linux_trapcode(int code)
949016ec05SDmitry Chagin {
959016ec05SDmitry Chagin
969016ec05SDmitry Chagin return (code < nitems(_bsd_to_linux_trapcode) ?
979016ec05SDmitry Chagin _bsd_to_linux_trapcode[code] : LINUX_T_UNKNOWN);
989016ec05SDmitry Chagin }
99*4281dab8SDmitry Chagin
100*4281dab8SDmitry Chagin u_int
linux_x86_elf_hwcap2(void)101*4281dab8SDmitry Chagin linux_x86_elf_hwcap2(void)
102*4281dab8SDmitry Chagin {
103*4281dab8SDmitry Chagin static u_int elf_hwcap2 = 0;
104*4281dab8SDmitry Chagin static bool elf_hwcap2_valid = false;
105*4281dab8SDmitry Chagin
106*4281dab8SDmitry Chagin if (!elf_hwcap2_valid) {
107*4281dab8SDmitry Chagin if ((cpu_stdext_feature & CPUID_STDEXT_FSGSBASE) != 0)
108*4281dab8SDmitry Chagin elf_hwcap2 |= LINUX_HWCAP2_FSGSBASE;
109*4281dab8SDmitry Chagin elf_hwcap2_valid = true;
110*4281dab8SDmitry Chagin }
111*4281dab8SDmitry Chagin return (elf_hwcap2);
112*4281dab8SDmitry Chagin }
113