aboutsummaryrefslogtreecommitdiff
path: root/i386
diff options
context:
space:
mode:
authorDamien Zammit <damien@zamaudio.com>2023-08-13 00:51:02 +0200
committerSamuel Thibault <samuel.thibault@ens-lyon.org>2023-08-13 00:51:02 +0200
commit6dcf01215edfd49a97c86e7c0d49e0d75785cf84 (patch)
treeca058ebedd32853617f92ced7bb4b3c5944744f7 /i386
parent8ff5ff4001e2f6c2361f452db6f7f468ea3a84b9 (diff)
downloadgnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.tar.gz
gnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.tar.bz2
gnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.zip
i386/x86_64: Add remote AST via IPI mechanism
Diffstat (limited to 'i386')
-rw-r--r--i386/i386/ast_check.c4
-rw-r--r--i386/i386/i386asm.sym1
-rw-r--r--i386/i386/locore.S1
-rw-r--r--i386/i386/smp.c16
-rw-r--r--i386/i386/smp.h1
-rw-r--r--i386/i386at/idt.h3
-rw-r--r--i386/i386at/int_init.c4
-rw-r--r--i386/i386at/interrupt.S8
8 files changed, 35 insertions, 3 deletions
diff --git a/i386/i386/ast_check.c b/i386/i386/ast_check.c
index 5121abf1..61cd5e87 100644
--- a/i386/i386/ast_check.c
+++ b/i386/i386/ast_check.c
@@ -34,6 +34,9 @@
#include <kern/ast.h>
#include <kern/processor.h>
+#include <kern/smp.h>
+#include <machine/cpu_number.h>
+#include <machine/apic.h>
/*
* Initialize for remote invocation of ast_check.
@@ -47,6 +50,7 @@ void init_ast_check(const processor_t processor)
*/
void cause_ast_check(const processor_t processor)
{
+ smp_remote_ast(apic_get_cpu_apic_id(processor->slot_num));
}
#endif /* NCPUS > 1 */
diff --git a/i386/i386/i386asm.sym b/i386/i386/i386asm.sym
index 8af0c5d6..18b208e9 100644
--- a/i386/i386/i386asm.sym
+++ b/i386/i386/i386asm.sym
@@ -48,6 +48,7 @@
#include <i386/apic.h>
#include <i386/xen.h>
+expr CALL_LOCAL_AST_BASE
expr CALL_SINGLE_FUNCTION_BASE
offset ApicLocalUnit lu apic_id APIC_ID
diff --git a/i386/i386/locore.S b/i386/i386/locore.S
index cb0f063b..c8262e22 100644
--- a/i386/i386/locore.S
+++ b/i386/i386/locore.S
@@ -652,6 +652,7 @@ INTERRUPT(21)
INTERRUPT(22)
INTERRUPT(23)
#endif
+INTERRUPT(CALL_LOCAL_AST_BASE)
/* Invalidate TLB IPI to call pmap_update_interrupt() on a specific cpu */
INTERRUPT(CALL_SINGLE_FUNCTION_BASE)
#ifdef APIC
diff --git a/i386/i386/smp.c b/i386/i386/smp.c
index c0149a3b..f3810370 100644
--- a/i386/i386/smp.c
+++ b/i386/i386/smp.c
@@ -45,19 +45,19 @@ static void smp_data_init(void)
}
-void smp_pmap_update(unsigned apic_id)
+static void smp_send_ipi(unsigned apic_id, unsigned vector)
{
unsigned long flags;
cpu_intr_save(&flags);
- apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE, CALL_SINGLE_FUNCTION_BASE, apic_id);
+ apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, ASSERT, EDGE, vector, apic_id);
do {
cpu_pause();
} while(lapic->icr_low.delivery_status == SEND_PENDING);
- apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, DE_ASSERT, EDGE, CALL_SINGLE_FUNCTION_BASE, apic_id);
+ apic_send_ipi(NO_SHORTHAND, FIXED, PHYSICAL, DE_ASSERT, EDGE, vector, apic_id);
do {
cpu_pause();
@@ -66,6 +66,16 @@ void smp_pmap_update(unsigned apic_id)
cpu_intr_restore(flags);
}
+void smp_remote_ast(unsigned apic_id)
+{
+ smp_send_ipi(apic_id, CALL_LOCAL_AST_BASE);
+}
+
+void smp_pmap_update(unsigned apic_id)
+{
+ smp_send_ipi(apic_id, CALL_SINGLE_FUNCTION_BASE);
+}
+
/* See Intel IA32/64 Software Developer's Manual 3A Section 8.4.4.1 */
void smp_startup_cpu(unsigned apic_id, unsigned vector)
{
diff --git a/i386/i386/smp.h b/i386/i386/smp.h
index 1faa39cd..784936ea 100644
--- a/i386/i386/smp.h
+++ b/i386/i386/smp.h
@@ -22,6 +22,7 @@
#define _SMP_H_
int smp_init(void);
+void smp_remote_ast(unsigned apic_id);
void smp_pmap_update(unsigned apic_id);
void smp_startup_cpu(unsigned apic_id, unsigned vector);
diff --git a/i386/i386at/idt.h b/i386/i386at/idt.h
index f080bb12..1c30eb7d 100644
--- a/i386/i386at/idt.h
+++ b/i386/i386at/idt.h
@@ -37,6 +37,9 @@
/* IOAPIC spurious interrupt vector set to 0xff */
#define IOAPIC_SPURIOUS_BASE 0xff
+/* Remote -> local AST requests */
+#define CALL_LOCAL_AST_BASE 0xfa
+
/* Currently for TLB shootdowns */
#define CALL_SINGLE_FUNCTION_BASE 0xfb
diff --git a/i386/i386at/int_init.c b/i386/i386at/int_init.c
index e7fe7e31..e3c4b8c8 100644
--- a/i386/i386at/int_init.c
+++ b/i386/i386at/int_init.c
@@ -45,6 +45,10 @@ int_fill(struct real_gate *myidt)
int_entry_table[i], KERNEL_CS,
ACC_PL_K|ACC_INTR_GATE, 0);
}
+ fill_idt_gate(myidt, CALL_LOCAL_AST_BASE,
+ int_entry_table[i], KERNEL_CS,
+ ACC_PL_K|ACC_INTR_GATE, 0);
+ i++;
fill_idt_gate(myidt, CALL_SINGLE_FUNCTION_BASE,
int_entry_table[i], KERNEL_CS,
ACC_PL_K|ACC_INTR_GATE, 0);
diff --git a/i386/i386at/interrupt.S b/i386/i386at/interrupt.S
index e9e9c0ef..01198bf5 100644
--- a/i386/i386at/interrupt.S
+++ b/i386/i386at/interrupt.S
@@ -48,6 +48,9 @@ ENTRY(interrupt)
cmpl $CALL_SINGLE_FUNCTION_BASE,%eax /* was this a SMP call single function request? */
je _call_single
+ cmpl $CALL_LOCAL_AST_BASE,%eax /* was this a SMP remote -> local ast request? */
+ je _call_local_ast
+
subl $24,%esp /* Two local variables + 4 parameters */
movl %eax,S_IRQ /* save irq number */
@@ -129,4 +132,9 @@ _call_single:
call EXT(lapic_eoi) /* lapic EOI before the handler to allow extra update */
call EXT(pmap_update_interrupt) /* TODO: Allow other functions */
ret
+
+_call_local_ast:
+ call EXT(ast_check) /* AST check on this cpu */
+ call EXT(lapic_eoi) /* lapic EOI */
+ ret
END(interrupt)