soc: xtensa: esp32: reenable SMP for esp32

By enabling SMP option plus the APPCPU, also
completes the SMP port by adding the esp32
specific arch_sched_ipi() function

Signed-off-by: Felipe Neves <felipe.neves@espressif.com>
diff --git a/soc/xtensa/esp32/esp32-mp.c b/soc/xtensa/esp32/esp32-mp.c
index 63cc4b0..857ae29 100644
--- a/soc/xtensa/esp32/esp32-mp.c
+++ b/soc/xtensa/esp32/esp32-mp.c
@@ -5,8 +5,13 @@
  */
 
 /* Include esp-idf headers first to avoid redefining BIT() macro */
-#include <soc.h>
+#include "soc/dport_reg.h"
+#include "soc/gpio_periph.h"
+#include "soc/rtc_periph.h"
 
+#include <drivers/interrupt_controller/intc_esp32.h>
+#include <soc.h>
+#include <device.h>
 #include <zephyr.h>
 #include <spinlock.h>
 #include <kernel_structs.h>
@@ -33,9 +38,11 @@
 
 volatile struct cpustart_rec *start_rec;
 static void *appcpu_top;
-
+static bool cpus_active[CONFIG_MP_NUM_CPUS];
 static struct k_spinlock loglock;
 
+extern void z_sched_ipi(void);
+
 /* Note that the logging done here is ACTUALLY REQUIRED FOR RELIABLE
  * OPERATION!  At least one particular board will experience spurious
  * hangs during initialization (usually the APPCPU fails to start at
@@ -67,7 +74,6 @@
 static void appcpu_entry2(void)
 {
 	volatile int ps, ie;
-	smp_log("ESP32: APPCPU running");
 
 	/* Copy over VECBASE from the main CPU for an initial value
 	 * (will need to revisit this if we ever allow a user API to
@@ -92,6 +98,8 @@
 
 	__asm__ volatile("wsr.MISC0 %0" : : "r"(cpu));
 
+	smp_log("ESP32: APPCPU running");
+
 	*start_rec->alive = 1;
 	start_rec->fn(start_rec->arg);
 }
@@ -190,6 +198,34 @@
 	smp_log("ESP32: APPCPU start sequence complete");
 }
 
+IRAM_ATTR static inline uint32_t prid(void)
+{
+	uint32_t id;
+
+	__asm__ volatile (
+		"rsr.prid %0\n"
+		"extui %0,%0,13,1" : "=r" (id));
+	return id;
+}
+
+IRAM_ATTR static void esp_crosscore_isr(void *arg)
+{
+	ARG_UNUSED(arg);
+
+#ifdef CONFIG_SMP
+	/* Right now this interrupt is only used for IPIs */
+	z_sched_ipi();
+#endif
+
+	const int core_id = prid();
+
+	if (core_id == 0) {
+		DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, 0);
+	} else {
+		DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, 0);
+	}
+}
+
 void arch_start_cpu(int cpu_num, k_thread_stack_t *stack, int sz,
 		    arch_cpustart_t fn, void *arg)
 {
@@ -219,5 +255,36 @@
 	while (!alive_flag) {
 	}
 
+	cpus_active[0] = true;
+	cpus_active[CONFIG_MP_NUM_CPUS - 1] = true;
+
+	esp_intr_alloc(DT_IRQN(DT_NODELABEL(ipi0)),
+		ESP_INTR_FLAG_IRAM,
+		esp_crosscore_isr,
+		NULL,
+		NULL);
+
+	esp_intr_alloc(DT_IRQN(DT_NODELABEL(ipi1)),
+		ESP_INTR_FLAG_IRAM,
+		esp_crosscore_isr,
+		NULL,
+		NULL);
+
 	smp_log("ESP32: APPCPU initialized");
 }
+
+void arch_sched_ipi(void)
+{
+	const int core_id = prid();
+
+	if (core_id == 0) {
+		DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_0_REG, DPORT_CPU_INTR_FROM_CPU_0);
+	} else {
+		DPORT_WRITE_PERI_REG(DPORT_CPU_INTR_FROM_CPU_1_REG, DPORT_CPU_INTR_FROM_CPU_1);
+	}
+}
+
+IRAM_ATTR bool arch_cpu_active(int cpu_num)
+{
+	return cpus_active[cpu_num];
+}