diff options
author | Damien Zammit <damien@zamaudio.com> | 2023-08-13 00:51:02 +0200 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2023-08-13 00:51:02 +0200 |
commit | 6dcf01215edfd49a97c86e7c0d49e0d75785cf84 (patch) | |
tree | ca058ebedd32853617f92ced7bb4b3c5944744f7 | |
parent | 8ff5ff4001e2f6c2361f452db6f7f468ea3a84b9 (diff) | |
download | gnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.tar.gz gnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.tar.bz2 gnumach-6dcf01215edfd49a97c86e7c0d49e0d75785cf84.zip |
i386/x86_64: Add remote AST via IPI mechanism
-rw-r--r-- | i386/i386/ast_check.c | 4 | ||||
-rw-r--r-- | i386/i386/i386asm.sym | 1 | ||||
-rw-r--r-- | i386/i386/locore.S | 1 | ||||
-rw-r--r-- | i386/i386/smp.c | 16 | ||||
-rw-r--r-- | i386/i386/smp.h | 1 | ||||
-rw-r--r-- | i386/i386at/idt.h | 3 | ||||
-rw-r--r-- | i386/i386at/int_init.c | 4 | ||||
-rw-r--r-- | i386/i386at/interrupt.S | 8 | ||||
-rw-r--r-- | x86_64/interrupt.S | 3 |
9 files changed, 38 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) diff --git a/x86_64/interrupt.S b/x86_64/interrupt.S index c73b31e8..8e96a41e 100644 --- a/x86_64/interrupt.S +++ b/x86_64/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 + subq $16,%rsp /* Two local variables */ movl %eax,S_IRQ /* save irq number */ |