#define CCFSZ 0xc0 #define PCPU(field) \ %g7 + PC_ ## field #define PCPU_ADDR(field, reg) \ add %g7, PC_ ## field, reg #define SET(label, r2, r1) \ setx label, r2, r1 #define PC_IRHEAD 0x0 #define PC_IRTAIL 0x8 #define PC_IRFREE 0x10 #define IR_NEXT 0x0 #define IR_FUNC 0x8 #define IR_ARG 0x10 #define IR_VEC 0x18 #define IV_SHIFT 5 #define IV_FUNC 0x0 #define IV_ARG 0x8 #define IV_PRI 0x10 #define SIG_BLOCK 1 #define SIG_UNBLOCK 2 #define INTR_DISABLE() \ SET(sigmask, %o2, %o1) ; \ clr %o2 ; \ call sigprocmask ; \ mov SIG_BLOCK, %o0 #define INTR_RESTORE() \ SET(sigmask, %o2, %o1) ; \ clr %o2 ; \ call sigprocmask ; \ mov SIG_UNBLOCK, %o0 #define SOFTINT(pri) \ call getpid ; \ nop ; \ call kill ; \ mov pri, %o1 .text .globl intr_dequeue .align 16 intr_dequeue: save %sp, -CCFSZ, %sp /* * intr_disable(); * if ((ir = pcpu->pc_irhead) == NULL) { * intr_restore(); * return; * } */ INTR_DISABLE() 1: ldx [PCPU(IRHEAD)], %l0 brnz,a,pt %l0, 2f nop INTR_RESTORE() ret restore /* * if ((pcpu->pc_irhead = ir->ir_next) == NULL) * pcpu->pc_irtail = &pcpu->pc_irhead; */ 2: ldx [%l0 + IR_NEXT], %l1 brnz,pt %l1, 3f stx %l1, [PCPU(IRHEAD)] PCPU_ADDR(IRHEAD, %l1) stx %l1, [PCPU(IRTAIL)] /* * func = ir->ir_func; * arg = ir->ir_arg; * vec = ir->ir_vec; */ 3: ldx [%l0 + IR_FUNC], %l2 ldx [%l0 + IR_ARG], %l3 ldx [%l0 + IR_VEC], %l4 /* * ir->ir_next = pcpu->pc_irfree; * pcpu->pc_irfree = ir; * intr_restore(); */ ldx [PCPU(IRFREE)], %l1 stx %l1, [%l0 + IR_NEXT] stx %l0, [PCPU(IRFREE)] INTR_RESTORE() /* * func(arg); * goto 1; */ call %l2 mov %l3, %o0 ba,a %xcc, 1b nop .globl intr_enqueue .align 16 intr_enqueue: save %sp, -CCFSZ, %sp /* * vec = ldxa(AA_SDB_INTR_D0, ASI_SDB_INTR_R); */ mov %i0, %g3 /* * func = ldxa(AA_SDB_INTR_D1, ASI_SDB_INTR_R); * arg = ldxa(AA_SDB_INTR_D2, ASI_SDB_INTR_R); * * if (func != NULL) { * func(arg); * // NOTREACHED * } * // above not shown * * iv = &intr_vectors[vec]; * func = iv->iv_func; * arg = iv->iv_arg; * pri = iv->iv_pri; */ SET(intr_vectors, %g4, %g2) sllx %g3, IV_SHIFT, %g4 add %g2, %g4, %g2 ldx [%g2 + IV_FUNC], %g4 ldx [%g2 + IV_ARG], %g5 ldx [%g2 + IV_PRI], %g6 /* * ir = pcpu->pc_irfree; * pcpu->pc_irfree = ir->ir_next; */ ldx [PCPU(IRFREE)], %g1 ldx [%g1 + IR_NEXT], %g2 stx %g2, [PCPU(IRFREE)] /* * ir->ir_vec = vec; * ir->ir_func = func; * ir->ir_arg = arg; */ stx %g3, [%g1 + IR_VEC] stx %g4, [%g1 + IR_FUNC] stx %g5, [%g1 + IR_ARG] /* * ir->ir_next = NULL; * *pcpu->pc_irtail = ir; * pcpu->pc_irtail = &ir->ir_next; */ stx %g0, [%g1 + IR_NEXT] ldx [PCPU(IRTAIL)], %g4 stx %g1, [%g4] add %g1, IR_NEXT, %g1 stx %g1, [PCPU(IRTAIL)] /* * wr(asr20, 0, 1 << pri) */ SOFTINT(%g6); ret restore