testsuite: utils: use IPI instead of int instruction for testing on x86

For x86, make the testing purpose trigger_irq() function to send
interrupt processor interrupt to CPU by APIC, instead of executing
INT instruction. Doing this because:
1. It can be controlled by irq lock, more close to trigger irq.
2. We don't need to hardcode the interrupt vector.

Signed-off-by: Enjia Mai <enjiax.mai@intel.com>
diff --git a/subsys/testsuite/include/interrupt_util.h b/subsys/testsuite/include/interrupt_util.h
index 6baeaf6..fbcd88c 100644
--- a/subsys/testsuite/include/interrupt_util.h
+++ b/subsys/testsuite/include/interrupt_util.h
@@ -101,8 +101,31 @@
 }
 
 #elif defined(CONFIG_X86)
+#include <drivers/interrupt_controller/loapic.h>
+#include <sys/arch_interface.h>
 
-#define trigger_irq(irq) __asm__ volatile("int %0" : : "i" (irq) : "memory")
+#define TRIGGER_IRQ_INT(vector) __asm__ volatile("int %0" : : "i" (vector) : "memory")
+
+/*
+ * Write Local APIC's ICR to trigger IPI for testing
+ * Delivery Mode: Fixed
+ * Destination Mode: Physical
+ * Level: Assert
+ * Trigger Mode: Edge
+ * Destination Shorthand: No Shorthand
+ * Destination: depends on cpu_id
+ */
+#define LOAPIC_ICR_IPI_TEST  0x00004000U
+
+static inline void trigger_irq(int vector)
+{
+#ifdef CONFIG_SMP
+	int cpu_id = arch_curr_cpu()->id;
+#else
+	int cpu_id = 0;
+#endif
+	z_loapic_ipi(cpu_id, LOAPIC_ICR_IPI_TEST, vector);
+}
 
 #elif defined(CONFIG_ARCH_POSIX)
 #include "irq_ctrl.h"