From 345b5e7cc0c5ecf57573b08d6267a32c42b03f45 Mon Sep 17 00:00:00 2001 From: dfr Date: Thu, 12 Oct 2000 17:47:01 +0000 Subject: [PATCH] Implement a rudimentary interrupt handling system which should be good enough for clock interrupts in SKI. --- sys/ia64/ia64/autoconf.c | 2 +- sys/ia64/ia64/clock.c | 2 +- sys/ia64/ia64/exception.S | 39 +++++++++++++++++- sys/ia64/ia64/exception.s | 39 +++++++++++++++++- sys/ia64/ia64/interrupt.c | 79 +++++-------------------------------- sys/ia64/ia64/machdep.c | 2 +- sys/ia64/include/cpu.h | 3 +- sys/ia64/include/ia64_cpu.h | 9 +++++ 8 files changed, 96 insertions(+), 79 deletions(-) diff --git a/sys/ia64/ia64/autoconf.c b/sys/ia64/ia64/autoconf.c index 66230b7023d..59edff84eed 100644 --- a/sys/ia64/ia64/autoconf.c +++ b/sys/ia64/ia64/autoconf.c @@ -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; } diff --git a/sys/ia64/ia64/clock.c b/sys/ia64/ia64/clock.c index 01783c46f24..e2b5fa73fa8 100644 --- a/sys/ia64/ia64/clock.c +++ b/sys/ia64/ia64/clock.c @@ -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(); diff --git a/sys/ia64/ia64/exception.S b/sys/ia64/ia64/exception.S index ed815ad1f4b..8424a7eac75 100644 --- a/sys/ia64/ia64/exception.S +++ b/sys/ia64/ia64/exception.S @@ -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 diff --git a/sys/ia64/ia64/exception.s b/sys/ia64/ia64/exception.s index ed815ad1f4b..8424a7eac75 100644 --- a/sys/ia64/ia64/exception.s +++ b/sys/ia64/ia64/exception.s @@ -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 diff --git a/sys/ia64/ia64/interrupt.c b/sys/ia64/ia64/interrupt.c index ec0ac51f34a..6fce33997cf 100644 --- a/sys/ia64/ia64/interrupt.c +++ b/sys/ia64/ia64/interrupt.c @@ -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); - } - 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); + 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_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 } diff --git a/sys/ia64/ia64/machdep.c b/sys/ia64/ia64/machdep.c index 612c3f04d85..8aef59ef1b7 100644 --- a/sys/ia64/ia64/machdep.c +++ b/sys/ia64/ia64/machdep.c @@ -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 diff --git a/sys/ia64/include/cpu.h b/sys/ia64/include/cpu.h index f14c20eb9ab..d1f4f86e7ec 100644 --- a/sys/ia64/include/cpu.h +++ b/sys/ia64/include/cpu.h @@ -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)); diff --git a/sys/ia64/include/ia64_cpu.h b/sys/ia64/include/ia64_cpu.h index 186e1368fff..2e10844510c 100644 --- a/sys/ia64/include/ia64_cpu.h +++ b/sys/ia64/include/ia64_cpu.h @@ -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. */ -- 2.45.2