mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-12 14:29:28 +00:00
Implement a rudimentary interrupt handling system which should be good
enough for clock interrupts in SKI.
This commit is contained in:
parent
d84feb93c4
commit
61e1efff8a
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67032
@ -94,7 +94,7 @@ configure(void *dummy)
|
||||
* Now we're ready to handle (pending) interrupts.
|
||||
* XXX this is slightly misplaced.
|
||||
*/
|
||||
spl0();
|
||||
enable_intr();
|
||||
|
||||
cold = 0;
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ cpu_initclocks()
|
||||
*/
|
||||
cycles_per_sec = 700000000;
|
||||
ia64_set_itm(ia64_get_itc() + (cycles_per_sec + hz/2) / hz);
|
||||
|
||||
ia64_set_itv(240); /* highest priority class */
|
||||
|
||||
freq = cycles_per_sec;
|
||||
last_time = ia64_get_itc();
|
||||
|
@ -52,7 +52,8 @@
|
||||
add r17=2f-1b,r17;; \
|
||||
mov b0=r17; \
|
||||
br.sptk.few exception_save; \
|
||||
2: alloc r14=ar.pfs,0,0,2,0; \
|
||||
2: (p3) ssm psr.i; \
|
||||
alloc r14=ar.pfs,0,0,2,0; \
|
||||
movl r15=exception_restore; \
|
||||
mov out0=_n_; \
|
||||
mov out1=sp;; \
|
||||
@ -511,7 +512,37 @@ ia64_vector_table:
|
||||
|
||||
/* 0x3000: External Interrupt vector */
|
||||
|
||||
TRAP(12)
|
||||
mov r16=b0 // save user's b0
|
||||
1: mov r17=ip;; // construct return address
|
||||
add r17=2f-1b,r17;; // for exception_save
|
||||
mov b0=r17
|
||||
br.sptk.few exception_save // 'call' exception_save
|
||||
|
||||
2: alloc r14=ar.pfs,0,0,2,0 // make a frame for calling with
|
||||
|
||||
mov out1=sp;;
|
||||
add sp=-16,sp;;
|
||||
|
||||
3: mov out0=cr.ivr // find interrupt vector
|
||||
;;
|
||||
cmp.eq p6,p0=15,out0 // check for spurious vector number
|
||||
(p6) br.dpnt.few exception_restore // if spurious, we are done
|
||||
;;
|
||||
ssm psr.i // re-enable interrupts
|
||||
;; // now that we are in-progress
|
||||
srlz.d
|
||||
;;
|
||||
br.call.sptk.many rp=interrupt // call high-level handler
|
||||
|
||||
rsm psr.i // disable interrupts
|
||||
;;
|
||||
srlz.d
|
||||
;;
|
||||
mov cr.eoi=r0 // and ack the interrupt
|
||||
;;
|
||||
srlz.d
|
||||
br.sptk.few 3b // loop for more
|
||||
|
||||
.align 1024
|
||||
|
||||
/* 0x3400: Reserved */
|
||||
@ -993,6 +1024,9 @@ ENTRY(exception_restore, 0)
|
||||
*
|
||||
* Return:
|
||||
* sp kernel stack pointer
|
||||
* p1 true if user mode
|
||||
* p2 true if kernel mode
|
||||
* p3 true if interrupts were enabled
|
||||
*/
|
||||
ENTRY(exception_save, 0)
|
||||
rsm psr.dt // turn off data translations
|
||||
@ -1005,6 +1039,7 @@ ENTRY(exception_save, 0)
|
||||
mov rIFA=cr.ifa
|
||||
mov rPR=pr
|
||||
;;
|
||||
tbit.nz p3,p0=rIPSR,14 // check for interrupt enable state
|
||||
extr.u r17=rIPSR,32,2 // extract ipsr.cpl
|
||||
;;
|
||||
cmp.eq p1,p2=r0,r17 // test for kernel mode
|
||||
|
@ -52,7 +52,8 @@
|
||||
add r17=2f-1b,r17;; \
|
||||
mov b0=r17; \
|
||||
br.sptk.few exception_save; \
|
||||
2: alloc r14=ar.pfs,0,0,2,0; \
|
||||
2: (p3) ssm psr.i; \
|
||||
alloc r14=ar.pfs,0,0,2,0; \
|
||||
movl r15=exception_restore; \
|
||||
mov out0=_n_; \
|
||||
mov out1=sp;; \
|
||||
@ -511,7 +512,37 @@ ia64_vector_table:
|
||||
|
||||
/* 0x3000: External Interrupt vector */
|
||||
|
||||
TRAP(12)
|
||||
mov r16=b0 // save user's b0
|
||||
1: mov r17=ip;; // construct return address
|
||||
add r17=2f-1b,r17;; // for exception_save
|
||||
mov b0=r17
|
||||
br.sptk.few exception_save // 'call' exception_save
|
||||
|
||||
2: alloc r14=ar.pfs,0,0,2,0 // make a frame for calling with
|
||||
|
||||
mov out1=sp;;
|
||||
add sp=-16,sp;;
|
||||
|
||||
3: mov out0=cr.ivr // find interrupt vector
|
||||
;;
|
||||
cmp.eq p6,p0=15,out0 // check for spurious vector number
|
||||
(p6) br.dpnt.few exception_restore // if spurious, we are done
|
||||
;;
|
||||
ssm psr.i // re-enable interrupts
|
||||
;; // now that we are in-progress
|
||||
srlz.d
|
||||
;;
|
||||
br.call.sptk.many rp=interrupt // call high-level handler
|
||||
|
||||
rsm psr.i // disable interrupts
|
||||
;;
|
||||
srlz.d
|
||||
;;
|
||||
mov cr.eoi=r0 // and ack the interrupt
|
||||
;;
|
||||
srlz.d
|
||||
br.sptk.few 3b // loop for more
|
||||
|
||||
.align 1024
|
||||
|
||||
/* 0x3400: Reserved */
|
||||
@ -993,6 +1024,9 @@ ENTRY(exception_restore, 0)
|
||||
*
|
||||
* Return:
|
||||
* sp kernel stack pointer
|
||||
* p1 true if user mode
|
||||
* p2 true if kernel mode
|
||||
* p3 true if interrupts were enabled
|
||||
*/
|
||||
ENTRY(exception_save, 0)
|
||||
rsm psr.dt // turn off data translations
|
||||
@ -1005,6 +1039,7 @@ ENTRY(exception_save, 0)
|
||||
mov rIFA=cr.ifa
|
||||
mov rPR=pr
|
||||
;;
|
||||
tbit.nz p3,p0=rIPSR,14 // check for interrupt enable state
|
||||
extr.u r17=rIPSR,32,2 // extract ipsr.cpl
|
||||
;;
|
||||
cmp.eq p1,p2=r0,r17 // test for kernel mode
|
||||
|
@ -76,41 +76,13 @@ void (*perf_irq)(unsigned long, struct trapframe *) = dummy_perf;
|
||||
static u_int schedclk2;
|
||||
|
||||
void
|
||||
interrupt(a0, a1, a2, framep)
|
||||
unsigned long a0, a1, a2;
|
||||
struct trapframe *framep;
|
||||
interrupt(u_int64_t vector, struct trapframe *framep)
|
||||
{
|
||||
#if 0
|
||||
/*
|
||||
* Find our per-cpu globals.
|
||||
*/
|
||||
globalp = (struct globaldata *) alpha_pal_rdval();
|
||||
|
||||
atomic_add_int(&PCPU_GET(intr_nesting_level), 1);
|
||||
{
|
||||
struct proc* p = curproc;
|
||||
if (!p) p = &proc0;
|
||||
if ((caddr_t) framep < (caddr_t) p->p_addr + 1024) {
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
panic("possible stack overflow\n");
|
||||
}
|
||||
}
|
||||
|
||||
framep->tf_regs[FRAME_TRAPARG_A0] = a0;
|
||||
framep->tf_regs[FRAME_TRAPARG_A1] = a1;
|
||||
framep->tf_regs[FRAME_TRAPARG_A2] = a2;
|
||||
switch (a0) {
|
||||
case ALPHA_INTR_XPROC: /* interprocessor interrupt */
|
||||
CTR0(KTR_INTR|KTR_SMP, "interprocessor interrupt");
|
||||
smp_handle_ipi(framep); /* note: lock not taken */
|
||||
break;
|
||||
|
||||
case ALPHA_INTR_CLOCK: /* clock interrupt */
|
||||
switch (vector) {
|
||||
case 240: /* clock interrupt */
|
||||
CTR0(KTR_INTR, "clock interrupt");
|
||||
if (PCPU_GET(cpuno) != hwrpb->rpb_primary_cpu_id) {
|
||||
CTR0(KTR_INTR, "ignoring clock on secondary");
|
||||
return;
|
||||
}
|
||||
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
cnt.v_intr++;
|
||||
@ -119,53 +91,20 @@ interrupt(a0, a1, a2, framep)
|
||||
#else
|
||||
intrcnt[INTRCNT_CLOCK]++;
|
||||
#endif
|
||||
if (platform.clockintr){
|
||||
(*platform.clockintr)(framep);
|
||||
/* divide hz (1024) by 8 to get stathz (128) */
|
||||
if((++schedclk2 & 0x7) == 0)
|
||||
statclock((struct clockframe *)framep);
|
||||
}
|
||||
hardclock((struct clockframe *)framep);
|
||||
setdelayed();
|
||||
/* divide hz (1024) by 8 to get stathz (128) */
|
||||
if((++schedclk2 & 0x7) == 0)
|
||||
statclock((struct clockframe *)framep);
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
break;
|
||||
|
||||
case ALPHA_INTR_ERROR: /* Machine Check or Correctable Error */
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
a0 = alpha_pal_rdmces();
|
||||
if (platform.mcheck_handler)
|
||||
(*platform.mcheck_handler)(a0, framep, a1, a2);
|
||||
else
|
||||
machine_check(a0, framep, a1, a2);
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
break;
|
||||
|
||||
case ALPHA_INTR_DEVICE: /* I/O device interrupt */
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
cnt.v_intr++;
|
||||
if (platform.iointr)
|
||||
(*platform.iointr)(framep, a1);
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
break;
|
||||
|
||||
case ALPHA_INTR_PERF: /* interprocessor interrupt */
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
perf_irq(a1, framep);
|
||||
mtx_exit(&Giant, MTX_DEF);
|
||||
break;
|
||||
|
||||
case ALPHA_INTR_PASSIVE:
|
||||
#if 0
|
||||
printf("passive release interrupt vec 0x%lx (ignoring)\n", a1);
|
||||
#endif
|
||||
break;
|
||||
|
||||
default:
|
||||
mtx_enter(&Giant, MTX_DEF);
|
||||
panic("unexpected interrupt: type 0x%lx vec 0x%lx a2 0x%lx\n",
|
||||
a0, a1, a2);
|
||||
panic("unexpected interrupt: vec %ld\n", vector);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
atomic_subtract_int(&PCPU_GET(intr_nesting_level), 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -1033,7 +1033,7 @@ setregs(struct proc *p, u_long entry, u_long stack, u_long ps_strings)
|
||||
bzero(frame->tf_f, sizeof(frame->tf_f));
|
||||
frame->tf_cr_iip = entry;
|
||||
frame->tf_cr_ipsr = (IA64_PSR_IC
|
||||
/* | IA64_PSR_I XXX not yet */
|
||||
| IA64_PSR_I
|
||||
| IA64_PSR_IT
|
||||
| IA64_PSR_DT
|
||||
| IA64_PSR_RT
|
||||
|
@ -151,8 +151,7 @@ void ia64_fpstate_save __P((struct proc *p, int write));
|
||||
void ia64_fpstate_drop __P((struct proc *p));
|
||||
void ia64_fpstate_switch __P((struct proc *p));
|
||||
void init_prom_interface __P((struct rpb*));
|
||||
void interrupt
|
||||
__P((unsigned long, unsigned long, unsigned long, struct trapframe *));
|
||||
void interrupt __P((u_int64_t, struct trapframe *));
|
||||
void machine_check
|
||||
__P((unsigned long, struct trapframe *, unsigned long, unsigned long));
|
||||
u_int64_t hwrpb_checksum __P((void));
|
||||
|
@ -409,6 +409,15 @@ ia64_set_itm(u_int64_t v)
|
||||
__asm __volatile("mov cr.itm=%0" :: "r" (v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the value of ar.itv.
|
||||
*/
|
||||
static __inline void
|
||||
ia64_set_itv(u_int64_t v)
|
||||
{
|
||||
__asm __volatile("mov cr.itv=%0" :: "r" (v));
|
||||
}
|
||||
|
||||
/*
|
||||
* Write a region register.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user