1
0
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:
Doug Rabson 2000-10-12 17:47:01 +00:00
parent d84feb93c4
commit 61e1efff8a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=67032
8 changed files with 96 additions and 79 deletions

View File

@ -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;
}

View File

@ -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();

View File

@ -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

View File

@ -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

View File

@ -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
}

View File

@ -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

View File

@ -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));

View File

@ -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.
*/