MFi386:
- 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:
parent
7331342177
commit
333b8de537
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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_ */
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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_ */
|
||||
|
Loading…
Reference in New Issue
Block a user