- Move PUSH_FRAME and POP_FRAME to asmacros.h and use PUSH_FRAME in
  atpic entry points.
- Move PCPU_* asm macros out of the middle of the asm profiling macros.
- Pass IRQ vector argument as an int rather than void * to reduce diffs
  with i386.
- EOI the lapic in C for the lapic timer handler.
- GC unused Xcpuast function.
- Split IPI_STOP handling code of ipi_nmi_handler() out into a
  cpustop_handler() function and call it from Xcpustop rather than
  duplicating all the logic in assembly.
- Fixup the list of symbols with interrupt frames in ddb traces.
  Xatpic_fastintr* have never existed on amd64, and the lapic timer
  handler and various IPI handlers were missing.
- Use trapframe instead of intrframe for interrupt entry points (on amd64
  the interrupt vector was already a separate argument, so the two frames
  were already identical) and GC intrframe.

Submitted by:	peter (3)
This commit is contained in:
John Baldwin 2005-12-08 18:33:30 +00:00
parent 7331342177
commit 333b8de537
13 changed files with 101 additions and 186 deletions

View File

@ -41,53 +41,6 @@
#include "assym.s"
/*
* Macros to create and destroy a trap frame.
*/
#define PUSH_FRAME \
subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \
testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
jz 1f ; /* Yes, dont swapgs again */ \
swapgs ; \
1: movq %rdi,TF_RDI(%rsp) ; \
movq %rsi,TF_RSI(%rsp) ; \
movq %rdx,TF_RDX(%rsp) ; \
movq %rcx,TF_RCX(%rsp) ; \
movq %r8,TF_R8(%rsp) ; \
movq %r9,TF_R9(%rsp) ; \
movq %rax,TF_RAX(%rsp) ; \
movq %rbx,TF_RBX(%rsp) ; \
movq %rbp,TF_RBP(%rsp) ; \
movq %r10,TF_R10(%rsp) ; \
movq %r11,TF_R11(%rsp) ; \
movq %r12,TF_R12(%rsp) ; \
movq %r13,TF_R13(%rsp) ; \
movq %r14,TF_R14(%rsp) ; \
movq %r15,TF_R15(%rsp)
#define POP_FRAME \
movq TF_RDI(%rsp),%rdi ; \
movq TF_RSI(%rsp),%rsi ; \
movq TF_RDX(%rsp),%rdx ; \
movq TF_RCX(%rsp),%rcx ; \
movq TF_R8(%rsp),%r8 ; \
movq TF_R9(%rsp),%r9 ; \
movq TF_RAX(%rsp),%rax ; \
movq TF_RBX(%rsp),%rbx ; \
movq TF_RBP(%rsp),%rbp ; \
movq TF_R10(%rsp),%r10 ; \
movq TF_R11(%rsp),%r11 ; \
movq TF_R12(%rsp),%r12 ; \
movq TF_R13(%rsp),%r13 ; \
movq TF_R14(%rsp),%r14 ; \
movq TF_R15(%rsp),%r15 ; \
testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
jz 1f ; /* keep kernel GS.base */ \
cli ; \
swapgs ; \
1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
/*
* I/O Interrupt Entry Point. Rather than having one entry point for
* each interrupt source, we use one entry point for each 32-bit word
@ -107,7 +60,7 @@ IDTVEC(vec_name) ; \
jz 2f ; \
addl $(32 * index),%eax ; \
1: ; \
movq %rax, %rdi ; /* pass the IRQ */ \
movl %eax, %edi ; /* pass the IRQ */ \
call lapic_handle_intr ; \
MEXITCOUNT ; \
jmp doreti ; \
@ -144,10 +97,6 @@ IDTVEC(spuriousint)
SUPERALIGN_TEXT
IDTVEC(timerint)
PUSH_FRAME
movq lapic, %rdx
movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */
FAKE_MCOUNT(TF_RIP(%rsp))
call lapic_handle_timer
@ -227,8 +176,7 @@ IDTVEC(invlrng)
*/
.text
SUPERALIGN_TEXT
IDTVEC(ipi_intr_bitmap_handler)
IDTVEC(ipi_intr_bitmap_handler)
PUSH_FRAME
movq lapic, %rdx
@ -240,27 +188,6 @@ IDTVEC(ipi_intr_bitmap_handler)
MEXITCOUNT
jmp doreti
/*
* Executed by a CPU when it receives an Xcpuast IPI from another CPU,
*
* The other CPU has already executed aston() or need_resched() on our
* current process, so we simply need to ack the interrupt and return
* via doreti to run ast().
*/
.text
SUPERALIGN_TEXT
IDTVEC(cpuast)
PUSH_FRAME
movq lapic, %rdx
movl $0, LA_EOI(%rdx) /* End Of Interrupt to APIC */
FAKE_MCOUNT(TF_RIP(%rsp))
MEXITCOUNT
jmp doreti
/*
* Executed by a CPU when it receives an Xcpustop IPI from another CPU,
*
@ -276,34 +203,8 @@ IDTVEC(cpustop)
movq lapic, %rax
movl $0, LA_EOI(%rax) /* End Of Interrupt to APIC */
movl PCPU(CPUID), %eax
imull $PCB_SIZE, %eax
leaq stoppcbs(%rax), %rdi
call savectx /* Save process context */
movl PCPU(CPUID), %eax
call cpustop_handler
lock
btsl %eax, stopped_cpus /* stopped_cpus |= (1<<id) */
1:
btl %eax, started_cpus /* while (!(started_cpus & (1<<id))) */
jnc 1b
lock
btrl %eax, started_cpus /* started_cpus &= ~(1<<id) */
lock
btrl %eax, stopped_cpus /* stopped_cpus &= ~(1<<id) */
test %eax, %eax
jnz 2f
movq cpustop_restartfunc, %rax
testq %rax, %rax
jz 2f
movq $0, cpustop_restartfunc /* One-shot */
call *%rax
2:
POP_FRAME
iretq

View File

@ -318,8 +318,11 @@ db_nextframe(struct amd64_frame **fp, db_addr_t *ip, struct thread *td)
strcmp(name, "nmi_calltrap") == 0)
frame_type = TRAP;
else if (strncmp(name, "Xatpic_intr", 11) == 0 ||
strncmp(name, "Xatpic_fastintr", 15) == 0 ||
strncmp(name, "Xapic_isr", 9) == 0)
strncmp(name, "Xapic_isr", 9) == 0 ||
strcmp(name, "Xtimerint") == 0 ||
strcmp(name, "Xipi_intr_bitmap_handler") == 0 ||
strcmp(name, "Xcpustop") == 0 ||
strcmp(name, "Xrendezvous") == 0)
frame_type = INTERRUPT;
else if (strcmp(name, "Xfast_syscall") == 0)
frame_type = SYSCALL;

View File

@ -149,7 +149,7 @@ intr_config_intr(int vector, enum intr_trigger trig, enum intr_polarity pol)
}
void
intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe)
intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame)
{
struct thread *td;
struct intr_event *ie;
@ -197,7 +197,7 @@ intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe)
* Execute fast interrupt handlers directly.
* To support clock handlers, if a handler registers
* with a NULL argument, then we pass it a pointer to
* an intrframe as its argument.
* a trapframe as its argument.
*/
td->td_intr_nesting_level++;
thread = 0;
@ -208,10 +208,10 @@ intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe)
continue;
}
CTR4(KTR_INTR, "%s: exec %p(%p) for %s", __func__,
ih->ih_handler, ih->ih_argument == NULL ? iframe :
ih->ih_handler, ih->ih_argument == NULL ? frame :
ih->ih_argument, ih->ih_name);
if (ih->ih_argument == NULL)
ih->ih_handler(iframe);
ih->ih_handler(frame);
else
ih->ih_handler(ih->ih_argument);
}

View File

@ -46,7 +46,6 @@ __FBSDID("$FreeBSD$");
#include <sys/mutex.h>
#include <sys/pcpu.h>
#include <sys/smp.h>
#include <sys/proc.h>
#include <vm/vm.h>
#include <vm/pmap.h>
@ -607,14 +606,13 @@ lapic_eoi(void)
}
void
lapic_handle_intr(void *cookie, struct intrframe frame)
lapic_handle_intr(int vector, struct trapframe frame)
{
struct intsrc *isrc;
int vec = (uintptr_t)cookie;
if (vec == -1)
if (vector == -1)
panic("Couldn't get vector from ISR!");
isrc = intr_lookup_source(apic_idt_to_irq(vec));
isrc = intr_lookup_source(apic_idt_to_irq(vector));
intr_execute_handlers(isrc, &frame);
}
@ -623,6 +621,10 @@ lapic_handle_timer(struct clockframe frame)
{
struct lapic *la;
/* Send EOI first thing. */
lapic_eoi();
/* Look up our local APIC structure for the tick counters. */
la = &lapics[PCPU_GET(apic_id)];
(*la->la_timer_count)++;
critical_enter();

View File

@ -1068,15 +1068,29 @@ ipi_nmi_selected(u_int32_t cpus)
}
int
ipi_nmi_handler()
ipi_nmi_handler(void)
{
int cpu = PCPU_GET(cpuid);
int cpumask = PCPU_GET(cpumask);
if (!(ipi_nmi_pending & cpumask))
return 1;
atomic_clear_int(&ipi_nmi_pending, cpumask);
cpustop_handler();
return 0;
}
#endif /* STOP_NMI */
/*
* Handle an IPI_STOP by saving our current context and spinning until we
* are resumed.
*/
void
cpustop_handler(void)
{
int cpu = PCPU_GET(cpuid);
int cpumask = PCPU_GET(cpumask);
savectx(&stoppcbs[cpu]);
@ -1094,11 +1108,7 @@ ipi_nmi_handler()
cpustop_restartfunc();
cpustop_restartfunc = NULL;
}
return 0;
}
#endif /* STOP_NMI */
/*
* This is called once the rest of the system is up and running and we're

View File

@ -201,7 +201,7 @@ int lapic_intr_pending(u_int vector);
void lapic_ipi_raw(register_t icrlo, u_int dest);
void lapic_ipi_vectored(u_int vector, int dest);
int lapic_ipi_wait(int delay);
void lapic_handle_intr(void *cookie, struct intrframe frame);
void lapic_handle_intr(int vector, struct trapframe frame);
void lapic_handle_timer(struct clockframe frame);
void lapic_set_logical_id(u_int apic_id, u_int cluster, u_int cluster_id);
int lapic_set_lvt_mask(u_int apic_id, u_int lvt, u_char masked);

View File

@ -59,12 +59,6 @@
#define NON_GPROF_ENTRY(name) GEN_ENTRY(name)
#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */
#ifdef LOCORE
#define PCPU(member) %gs:PC_ ## member
#define PCPU_ADDR(member, reg) movq %gs:PC_PRVSPACE,reg; \
addq $PC_ ## member,reg
#endif
#ifdef GPROF
/*
* __mcount is like [.]mcount except that doesn't require its caller to set
@ -141,6 +135,60 @@
#define IDTVEC(name) ALIGN_TEXT; .globl __CONCAT(X,name); \
.type __CONCAT(X,name),@function; __CONCAT(X,name):
/*
* Macros to create and destroy a trap frame.
*/
#define PUSH_FRAME \
subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \
testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
jz 1f ; /* Yes, dont swapgs again */ \
swapgs ; \
1: movq %rdi,TF_RDI(%rsp) ; \
movq %rsi,TF_RSI(%rsp) ; \
movq %rdx,TF_RDX(%rsp) ; \
movq %rcx,TF_RCX(%rsp) ; \
movq %r8,TF_R8(%rsp) ; \
movq %r9,TF_R9(%rsp) ; \
movq %rax,TF_RAX(%rsp) ; \
movq %rbx,TF_RBX(%rsp) ; \
movq %rbp,TF_RBP(%rsp) ; \
movq %r10,TF_R10(%rsp) ; \
movq %r11,TF_R11(%rsp) ; \
movq %r12,TF_R12(%rsp) ; \
movq %r13,TF_R13(%rsp) ; \
movq %r14,TF_R14(%rsp) ; \
movq %r15,TF_R15(%rsp)
#define POP_FRAME \
movq TF_RDI(%rsp),%rdi ; \
movq TF_RSI(%rsp),%rsi ; \
movq TF_RDX(%rsp),%rdx ; \
movq TF_RCX(%rsp),%rcx ; \
movq TF_R8(%rsp),%r8 ; \
movq TF_R9(%rsp),%r9 ; \
movq TF_RAX(%rsp),%rax ; \
movq TF_RBX(%rsp),%rbx ; \
movq TF_RBP(%rsp),%rbp ; \
movq TF_R10(%rsp),%r10 ; \
movq TF_R11(%rsp),%r11 ; \
movq TF_R12(%rsp),%r12 ; \
movq TF_R13(%rsp),%r13 ; \
movq TF_R14(%rsp),%r14 ; \
movq TF_R15(%rsp),%r15 ; \
testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
jz 1f ; /* keep kernel GS.base */ \
cli ; \
swapgs ; \
1: addq $TF_RIP,%rsp /* skip over tf_err, tf_trapno */
/*
* Access per-CPU data.
*/
#define PCPU(member) %gs:PC_ ## member
#define PCPU_ADDR(member, reg) \
movq %gs:PC_PRVSPACE, reg ; \
addq $PC_ ## member, reg
#endif /* LOCORE */
#endif /* !_MACHINE_ASMACROS_H_ */

View File

@ -76,36 +76,6 @@ struct trapframe {
register_t tf_ss;
};
/* Interrupt stack frame */
struct intrframe {
register_t if_rdi;
register_t if_rsi;
register_t if_rdx;
register_t if_rcx;
register_t if_r8;
register_t if_r9;
register_t if_rax;
register_t if_rbx;
register_t if_rbp;
register_t if_r10;
register_t if_r11;
register_t if_r12;
register_t if_r13;
register_t if_r14;
register_t if_r15;
register_t :64; /* compat with trap frame - trapno */
register_t :64; /* compat with trap frame - addr */
register_t :64; /* compat with trap frame - flags */
register_t :64; /* compat with trap frame - err */
/* below portion defined in hardware */
register_t if_rip;
register_t if_cs;
register_t if_rflags;
register_t if_rsp;
register_t if_ss;
};
/* frame of clock (same as interrupt frame) */
struct clockframe {

View File

@ -107,7 +107,7 @@ struct intsrc {
u_int is_index;
};
struct intrframe;
struct trapframe;
extern struct mtx icu_lock;
extern int elcr_found;
@ -121,7 +121,7 @@ int intr_add_handler(const char *name, int vector, driver_intr_t handler,
void *arg, enum intr_type flags, void **cookiep);
int intr_config_intr(int vector, enum intr_trigger trig,
enum intr_polarity pol);
void intr_execute_handlers(struct intsrc *isrc, struct intrframe *iframe);
void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame);
struct intsrc *intr_lookup_source(int vector);
int intr_register_source(struct intsrc *isrc);
int intr_remove_handler(void *cookie);

View File

@ -46,6 +46,7 @@ inthand_t
/* functions in mp_machdep.c */
void cpu_add(u_int apic_id, char boot_cpu);
void cpustop_handler(void);
void init_secondary(void);
void ipi_selected(u_int cpus, u_int ipi);
void ipi_all(u_int ipi);

View File

@ -45,7 +45,6 @@ __FBSDID("$FreeBSD$");
#include <sys/lock.h>
#include <sys/module.h>
#include <sys/mutex.h>
#include <sys/proc.h>
#include <machine/cpufunc.h>
#include <machine/frame.h>
@ -478,19 +477,18 @@ atpic_init(void *dummy __unused)
SYSINIT(atpic_init, SI_SUB_INTR, SI_ORDER_SECOND + 1, atpic_init, NULL)
void
atpic_handle_intr(void *cookie, struct intrframe iframe)
atpic_handle_intr(u_int vector, struct trapframe frame)
{
struct intsrc *isrc;
int vec = (uintptr_t)cookie;
KASSERT(vec < NUM_ISA_IRQS, ("unknown int %d\n", vec));
isrc = &atintrs[vec].at_intsrc;
KASSERT(vector < NUM_ISA_IRQS, ("unknown int %u\n", vector));
isrc = &atintrs[vector].at_intsrc;
/*
* If we don't have an event, see if this is a spurious
* interrupt.
*/
if (isrc->is_event == NULL && (vec == 7 || vec == 15)) {
if (isrc->is_event == NULL && (vector == 7 || vector == 15)) {
int port, isr;
/*
@ -506,7 +504,7 @@ atpic_handle_intr(void *cookie, struct intrframe iframe)
if ((isr & IRQ_MASK(7)) == 0)
return;
}
intr_execute_handlers(isrc, &iframe);
intr_execute_handlers(isrc, &frame);
}
#ifdef DEV_ISA

View File

@ -47,27 +47,9 @@
.text ; \
SUPERALIGN_TEXT ; \
IDTVEC(vec_name) ; \
subq $TF_RIP,%rsp ; /* skip dummy tf_err and tf_trapno */ \
testb $SEL_RPL_MASK,TF_CS(%rsp) ; /* come from kernel? */ \
jz 1f ; /* Yes, dont swapgs again */ \
swapgs ; \
1: movq %rdi,TF_RDI(%rsp) ; \
movq %rsi,TF_RSI(%rsp) ; \
movq %rdx,TF_RDX(%rsp) ; \
movq %rcx,TF_RCX(%rsp) ; \
movq %r8,TF_R8(%rsp) ; \
movq %r9,TF_R9(%rsp) ; \
movq %rax,TF_RAX(%rsp) ; \
movq %rbx,TF_RBX(%rsp) ; \
movq %rbp,TF_RBP(%rsp) ; \
movq %r10,TF_R10(%rsp) ; \
movq %r11,TF_R11(%rsp) ; \
movq %r12,TF_R12(%rsp) ; \
movq %r13,TF_R13(%rsp) ; \
movq %r14,TF_R14(%rsp) ; \
movq %r15,TF_R15(%rsp) ; \
PUSH_FRAME ; \
FAKE_MCOUNT(TF_RIP(%rsp)) ; \
movq $irq_num, %rdi; /* pass the IRQ */ \
movl $irq_num, %edi; /* pass the IRQ */ \
call atpic_handle_intr ; \
MEXITCOUNT ; \
jmp doreti

View File

@ -43,7 +43,7 @@
#define ICU_IMR_OFFSET 1
void atpic_handle_intr(void *cookie, struct intrframe iframe);
void atpic_handle_intr(u_int vector, struct trapframe frame);
void atpic_startup(void);
#endif /* !_AMD64_ISA_ICU_H_ */