1 /*
2 * Copyright (c) 2020 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/kernel.h>
8 #include <zephyr/ztest.h>
9 #include <zephyr/tc_util.h>
10
11 #include <kernel_internal.h>
12 #if defined(__GNUC__)
13 #include "test_asm_inline_gcc.h"
14 #else
15 #include "test_asm_inline_other.h"
16 #endif
17
18 static volatile int int_handler_executed;
19
20 extern uint8_t z_x86_nmi_stack0[];
21 extern uint8_t z_x86_nmi_stack1[];
22 extern uint8_t z_x86_nmi_stack2[];
23 extern uint8_t z_x86_nmi_stack3[];
24
25 uint8_t *nmi_stacks[] = {
26 z_x86_nmi_stack0,
27 #if CONFIG_MP_MAX_NUM_CPUS > 1
28 z_x86_nmi_stack1,
29 #if CONFIG_MP_MAX_NUM_CPUS > 2
30 z_x86_nmi_stack2,
31 #if CONFIG_MP_MAX_NUM_CPUS > 3
32 z_x86_nmi_stack3
33 #endif
34 #endif
35 #endif
36 };
37
z_x86_do_kernel_nmi(const struct arch_esf * esf)38 bool z_x86_do_kernel_nmi(const struct arch_esf *esf)
39 {
40 uint64_t stack;
41
42 _get_esp(stack);
43
44 TC_PRINT("ESP: 0x%llx CPU %d nmi_stack %p\n", stack,
45 arch_curr_cpu()->id, nmi_stacks[arch_curr_cpu()->id]);
46
47 zassert_true(stack > (uint64_t)nmi_stacks[arch_curr_cpu()->id] &&
48 stack < (uint64_t)nmi_stacks[arch_curr_cpu()->id] +
49 CONFIG_X86_EXCEPTION_STACK_SIZE, "Incorrect stack");
50
51 int_handler_executed++;
52
53 return true;
54 }
55
ZTEST(nmi,test_nmi_handler)56 ZTEST(nmi, test_nmi_handler)
57 {
58 TC_PRINT("Testing to see interrupt handler executes properly\n");
59
60 _trigger_isr_handler(IV_NON_MASKABLE_INTERRUPT);
61
62 zassert_not_equal(int_handler_executed, 0,
63 "Interrupt handler did not execute");
64 zassert_equal(int_handler_executed, 1,
65 "Interrupt handler executed more than once! (%d)\n",
66 int_handler_executed);
67 }
68
69 ZTEST_SUITE(nmi, NULL, NULL, NULL, NULL, NULL);
70