/* * copy_lines: Copy a range of lines to after given address. Return status. */ int copy_lines (off_t from, off_t to, off_t after, ed_buffer_t *ed) { ed_line_node_t *lp, *np; ed_undo_node_t *up = NULL; off_t ci[2]; int split = (from <= after && after < to); int i; ci[0] = (split ? after : to) - from + 1; ci[1] = (split ? to - after : 0); for (i = 0; i < 2; ++i) { lp = get_line_node (i == 0 ? from : after + 1, ed); for (; ci[i]-- > 0; lp = lp->q_forw) { spl1 (); if (!(np = append_line_node (lp->len, lp->seek, after, ed))) { spl0 (); return ERR; } ed->state->dot = ++after; APPEND_UNDO_NODE (np, up, after, ed); ed->state->is_modified = 1; spl0 (); } } return 0; }
/* batt_check() returns one of the following values: * 7: >4.6V full * 6: >4.5V ok * 5: >4.3V medium * 4: >4.0V low * 3: >3.7V very low * 2: >3.4V starving * 1: >3.2V almost dead * 0: <=3.2V dead (calculator is reset?) */ int batt_check() { int x = spl1(); int i, j; BATTCHECK |= 0x09; for (i = 6; i >= 0; --i) { reinit(); TRIGLEVEL = i << 7; for (j = 110; j >= 0; --j) { if (!(BATTSTAT & 0x04)) goto quit; }; }; quit: i = 6 - i; G.batt_level = i; BATTCHECK &= 0xf7; reinit(); BATTCHECK &= 0xf6; WAITSTATE = ~0; showstatus(); splx(x); return G.batt_level; }
/* * append_lines: Insert text from stdin to after given address; stop * when either a single period is read or EOF. Return status. */ int append_lines (off_t after, ed_buffer_t *ed) { char *s; size_t len; ed_line_node_t *lp; ed_undo_node_t *up = NULL; int status; ed->state->input_is_binary = 0; for (ed->state->dot = after;;) { if (!ed->exec->global) { if (!(ed->input = get_stdin_line (&len, ed))) { /* Permit EOF (i.e., key stroke: CTL + D) at beginning of line as alternative to `.' */ status = feof (stdin) ? 0 : ERR; clearerr (stdin); return status; } if (*(ed->input + len - 1) != '\n') { ed->exec->err = _("End-of-file unexpected"); clearerr (stdin); return ERR; } ++ed->exec->line_no; } else if (*ed->input == '\0') return 0; if (*ed->input == '.' && *(ed->input + 1) == '\n') { ++ed->input; return 0; } if (ed->exec->global) { for (s = ed->input; *s++ != '\n';) ; len = s - ed->input; } spl1 (); ed->state->is_binary |= ed->state->input_is_binary; if (after == ed->state->lines) ed->state->newline_appended = 0; if (!(ed->input = put_buffer_line (ed->input, len, ed))) { spl0 (); return ERR; } lp = get_line_node (ed->state->dot, ed); APPEND_UNDO_NODE (lp, up, ed->state->dot, ed); ed->state->is_empty = 0; ed->state->is_modified = 1; spl0 (); } /* NOTREACHED */ }
int parsendch(struct par_softc *sc, u_char ch) { int error = 0; int s; /* if either offline, busy or out of paper, wait for that condition to clear */ s = spl1(); while (!error && (parsend_pending || !(intio_get_sicilian_intr() & SICILIAN_STAT_PAR))) { /* wait a second, and try again */ callout_reset(&intr_callout, hz, parintr, 0); partimeout_pending = 1; /* this is essentially a flipflop to have us wait for the first character being transmitted when trying to transmit the second, etc. */ parsend_pending = 0; /* it's quite important that a parallel putc can be interrupted, given the possibility to lock a printer in an offline condition.. */ if ((error = tsleep(parintr, PCATCH|(PZERO-1), "parsendch", 0))) { #ifdef DEBUG if (pardebug & PDB_INTERRUPT) printf("parsendch interrupted, error = %d\n", error); #endif if (partimeout_pending) callout_stop(&intr_callout); partimeout_pending = 0; } } if (!error) { #ifdef DEBUG if (pardebug & PDB_INTERRUPT) printf("#%d", ch); #endif bus_space_write_1(sc->sc_bst, sc->sc_bsh, PAR_DATA, ch); DELAY(1); /* (DELAY(1) == 1us) > 0.5us */ bus_space_write_1(sc->sc_bst, sc->sc_bsh, PAR_STROBE, 0); intio_set_sicilian_intr(intio_get_sicilian_intr() | SICILIAN_INTR_PAR); DELAY(1); bus_space_write_1(sc->sc_bst, sc->sc_bsh, PAR_STROBE, 1); parsend_pending = 1; } splx(s); return error; }
/* * move_lines: Move a range of lines to after given address. Return status. */ int move_lines (off_t from, off_t to, off_t after, ed_buffer_t *ed) { ed_line_node_t *b1, *a1, *b2, *a2; off_t succ = INC_MOD (to, ed->state->lines); off_t prec = from - 1; int done = (after == from - 1 || after == to); spl1 (); if (done) { a2 = get_line_node (succ, ed); b2 = get_line_node (prec, ed); ed->state->dot = to; } else if (!append_undo_node (UMOV, prec, succ, ed) || !append_undo_node (UMOV, after, INC_MOD (after, ed->state->lines), ed)) { spl0 (); return ERR; } else { a1 = get_line_node (succ, ed); if (from > after) { b1 = get_line_node (prec, ed); /* this get_line_node last! */ b2 = get_line_node (after, ed); } else { b2 = get_line_node (after, ed); /* this get_line_node last! */ b1 = get_line_node (prec, ed); } a2 = b2->q_forw; LINK_NODES (b2, b1->q_forw); LINK_NODES (a1->q_back, a2); LINK_NODES (b1, a1); ed->state->dot = after + (from > after ? to - from + 1 : 0); } if (ed->exec->global) delete_global_nodes (b2->q_forw, a2, ed); ed->state->is_modified = 1; spl0 (); return 0; }
/* * next_global_node: Pop node from top of global queue; return line * node pointer. */ static ed_line_node_t * next_global_node (ed_buffer_t *ed) { ed_global_node_t *ap = ed->core->global_head->q_forw; ed_line_node_t *lp = ap->lp; if (ap != ed->core->global_head) { spl1 (); UNLINK_NODE (ap); free (ap); spl0 (); } return lp; }
int parclose(dev_t dev, int flags, int mode, struct lwp *l) { int unit = UNIT(dev); int s; struct par_softc *sc = device_lookup_private(&par_cd, unit); sc->sc_flags &= ~(PARF_OPEN|PARF_OWRITE); /* don't allow interrupts any longer */ s = spl1(); intio_set_sicilian_intr(intio_get_sicilian_intr() & ~SICILIAN_INTR_PAR); splx(s); return (0); }
void drsc_handler(void) { struct siop_softc *sc = drsc_softc; siop_regmap_p rp; int istat; if (sc->sc_flags & SIOP_INTSOFF) return; /* interrupts are not active */ rp = sc->sc_siopp; istat = rp->siop_istat; if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) return; /* * save interrupt status, DMA status, and SCSI status 0 * (may need to deal with stacked interrupts?) */ sc->sc_sstat0 = rp->siop_sstat0; sc->sc_istat = istat; sc->sc_dstat = rp->siop_dstat; /* * disable interrupts until the callback can process this * interrupt. */ #ifdef DRSC_NOCALLBACK (void)spl1(); siopintr(sc); #else rp->siop_sien = 0; rp->siop_dien = 0; sc->sc_flags |= SIOP_INTDEFER | SIOP_INTSOFF; single_inst_bclr_b(*draco_intpen, DRIRQ_SCSI); #ifdef DEBUG if (*draco_intpen & DRIRQ_SCSI) printf("%s: intpen still 0x%x\n", sc->sc_dev.dv_xname, *draco_intpen); #endif add_sicallback((sifunc_t)siopintr, sc, NULL); #endif return; }
/* mark_global_nodes: Add lines matching a pattern to global queue. */ int mark_global_nodes (int want_match, ed_buffer_t *ed) { regmatch_t rm[1]; regex_t *re; ed_line_node_t *lp; off_t from = ed->exec->region->start; off_t to = ed->exec->region->end; off_t n = from ? to - from + 1 : 0; char dc = *ed->input; /* pattern delimiting char */ char *s; spl1 (); if (!(re = get_compiled_regex (dc, RE_SEARCH, ed))) { spl0 (); return ERR; } if (*ed->input == dc && *ed->input != '\n') ++ed->input; reset_global_queue (ed); spl0 (); lp = get_line_node (from, ed); for (; n; --n, lp = lp->q_forw) { if (!(s = get_buffer_line (lp, ed))) return ERR; #ifdef REG_STARTEND rm->rm_so = 0; rm->rm_eo = lp->len; if ((!regexec (re, s, 0, rm, REG_STARTEND)) == want_match && !append_global_node (lp, ed)) #else if (ed->state->is_binary) NUL_TO_NEWLINE (s, lp->len); if (!regexec (re, s, 0, NULL, 0) == want_match && !append_global_node (lp, ed)) #endif /* !REG_STARTEND */ return ERR; } return 0; }
/* * append_global_node: Append node to end of global queue. Return node * pointer. */ static ed_global_node_t * append_global_node (const ed_line_node_t *lp, ed_buffer_t *ed) { ed_global_node_t *gp; ed_global_node_t *tq = ed->core->global_head->q_back; spl1 (); if (!(gp = (ed_global_node_t *) malloc (ED_GLOBAL_NODE_T_SIZE))) { fprintf (stderr, "%s\n", strerror (errno)); ed->exec->err = _("Memory exhausted"); spl0 (); return NULL; } gp->lp = (ed_line_node_t *) lp; /* APPEND_NODE is macro, so tq is mandatory! */ APPEND_NODE (gp, tq); spl0 (); return gp; }
/* * join_lines: Replace a range of lines with the joined text of those lines. */ int join_lines (off_t from, off_t to, ed_buffer_t *ed) { static char *lj = NULL; /* line join buffer */ static size_t lj_size; /* buffer size */ ed_line_node_t *lp = get_line_node (from, ed); off_t n = from ? to - from + 1 : 0; size_t len = 0; char *s; for (; n; --n, lp = lp->q_forw) { if (!(s = get_buffer_line (lp, ed))) return ERR; REALLOC_THROW (lj, lj_size, len + lp->len, ERR, ed); memcpy (lj + len, s, lp->len); len += lp->len; } REALLOC_THROW (lj, lj_size, len + 2, ERR, ed); memcpy (lj + len++, "\n", 2); spl1 (); if (delete_lines (from, to, ed) < 0) { spl0 (); return ERR; } ed->state->dot = from - 1; if (!put_buffer_line (lj, len, ed) || !append_undo_node (UADD, ed->state->dot, ed->state->dot, ed)) { spl0 (); return ERR; } ed->state->is_modified = 1; spl0 (); return 0; }
/*ARGSUSED*/ void trap(struct frame *fp, int type, unsigned code, unsigned v) { extern char fubail[], subail[]; struct lwp *l; struct proc *p; struct pcb *pcb; void *onfault; ksiginfo_t ksi; int s; int rv; u_quad_t sticks = 0 /* XXX initialiser works around compiler bug */; static int panicking __diagused; curcpu()->ci_data.cpu_ntrap++; l = curlwp; p = l->l_proc; pcb = lwp_getpcb(l); KSI_INIT_TRAP(&ksi); ksi.ksi_trap = type & ~T_USER; if (USERMODE(fp->f_sr)) { type |= T_USER; sticks = p->p_sticks; l->l_md.md_regs = fp->f_regs; LWP_CACHE_CREDS(l, p); } switch (type) { default: dopanic: /* * Let the kernel debugger see the trap frame that * caused us to panic. This is a convenience so * one can see registers at the point of failure. */ s = splhigh(); panicking = 1; printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); printf("%s program counter = 0x%x\n", (type & T_USER) ? "user" : "kernel", fp->f_pc); #ifdef KGDB /* If connected, step or cont returns 1 */ if (kgdb_trap(type, (db_regs_t *)fp)) goto kgdb_cont; #endif #ifdef DDB (void)kdb_trap(type, (db_regs_t *)fp); #endif #ifdef KGDB kgdb_cont: #endif splx(s); if (panicstr) { printf("trap during panic!\n"); #ifdef DEBUG /* XXX should be a machine-dependent hook */ printf("(press a key)\n"); (void)cngetc(); #endif } regdump((struct trapframe *)fp, 128); type &= ~T_USER; if ((u_int)type < trap_types) panic(trap_type[type]); panic("trap"); case T_BUSERR: /* kernel bus error */ onfault = pcb->pcb_onfault; if (onfault == NULL) goto dopanic; rv = EFAULT; /* FALLTHROUGH */ copyfault: /* * If we have arranged to catch this fault in any of the * copy to/from user space routines, set PC to return to * indicated location and set flag informing buserror code * that it may need to clean up stack frame. */ fp->f_stackadj = exframesize[fp->f_format]; fp->f_format = fp->f_vector = 0; fp->f_pc = (int)onfault; fp->f_regs[D0] = rv; return; case T_BUSERR|T_USER: /* bus error */ case T_ADDRERR|T_USER: /* address error */ ksi.ksi_addr = (void *)v; ksi.ksi_signo = SIGBUS; ksi.ksi_code = (type == (T_BUSERR|T_USER)) ? BUS_OBJERR : BUS_ADRERR; break; case T_COPERR: /* kernel coprocessor violation */ case T_FMTERR|T_USER: /* do all RTE errors come in as T_USER? */ case T_FMTERR: /* ...just in case... */ /* * The user has most likely trashed the RTE or FP state info * in the stack frame of a signal handler. */ printf("pid %d: kernel %s exception\n", p->p_pid, type==T_COPERR ? "coprocessor" : "format"); type |= T_USER; mutex_enter(p->p_lock); SIGACTION(p, SIGILL).sa_handler = SIG_DFL; sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); sigdelset(&l->l_sigmask, SIGILL); mutex_exit(p->p_lock); ksi.ksi_signo = SIGILL; ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was ILL_RESAD_FAULT */ ksi.ksi_code = (type == T_COPERR) ? ILL_COPROC : ILL_ILLOPC; break; case T_COPERR|T_USER: /* user coprocessor violation */ /* What is a proper response here? */ ksi.ksi_signo = SIGFPE; ksi.ksi_code = FPE_FLTINV; break; case T_FPERR|T_USER: /* 68881 exceptions */ /* * We pass along the 68881 status register which locore stashed * in code for us. */ ksi.ksi_signo = SIGFPE; ksi.ksi_code = fpsr2siginfocode(code); break; #ifdef M68040 case T_FPEMULI|T_USER: /* unimplemented FP instruction */ case T_FPEMULD|T_USER: /* unimplemented FP data type */ /* XXX need to FSAVE */ printf("pid %d(%s): unimplemented FP %s at %x (EA %x)\n", p->p_pid, p->p_comm, fp->f_format == 2 ? "instruction" : "data type", fp->f_pc, fp->f_fmt2.f_iaddr); /* XXX need to FRESTORE */ ksi.ksi_signo = SIGFPE; ksi.ksi_code = FPE_FLTINV; break; #endif case T_ILLINST|T_USER: /* illegal instruction fault */ case T_PRIVINST|T_USER: /* privileged instruction fault */ ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was ILL_PRIVIN_FAULT */ ksi.ksi_signo = SIGILL; ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ? ILL_PRVOPC : ILL_ILLOPC; break; case T_ZERODIV|T_USER: /* Divide by zero */ ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was FPE_INTDIV_TRAP */ ksi.ksi_signo = SIGFPE; ksi.ksi_code = FPE_FLTDIV; break; case T_CHKINST|T_USER: /* CHK instruction trap */ ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was FPE_SUBRNG_TRAP */ ksi.ksi_signo = SIGFPE; break; case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was FPE_INTOVF_TRAP */ ksi.ksi_signo = SIGFPE; break; /* * XXX: Trace traps are a nightmare. * * HP-UX uses trap #1 for breakpoints, * NetBSD/m68k uses trap #2, * SUN 3.x uses trap #15, * DDB and KGDB uses trap #15 (for kernel breakpoints; * handled elsewhere). * * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE. * SUN 3.x traps get passed through as T_TRAP15 and are not really * supported yet. * * XXX: We should never get kernel-mode T_TRAP15 * XXX: because locore.s now gives them special treatment. */ case T_TRAP15: /* kernel breakpoint */ #ifdef DEBUG printf("unexpected kernel trace trap, type = %d\n", type); printf("program counter = 0x%x\n", fp->f_pc); #endif fp->f_sr &= ~PSL_T; return; case T_TRACE|T_USER: /* user trace trap */ #ifdef COMPAT_SUNOS /* * SunOS uses Trap #2 for a "CPU cache flush". * Just flush the on-chip caches and return. */ if (p->p_emul == &emul_sunos) { ICIA(); DCIU(); return; } #endif /* FALLTHROUGH */ case T_TRACE: /* tracing a trap instruction */ case T_TRAP15|T_USER: /* SUN user trace trap */ fp->f_sr &= ~PSL_T; ksi.ksi_signo = SIGTRAP; break; case T_ASTFLT: /* system async trap, cannot happen */ goto dopanic; case T_ASTFLT|T_USER: /* user async trap */ astpending = 0; /* * We check for software interrupts first. This is because * they are at a higher level than ASTs, and on a VAX would * interrupt the AST. We assume that if we are processing * an AST that we must be at IPL0 so we don't bother to * check. Note that we ensure that we are at least at SIR * IPL while processing the SIR. */ spl1(); /* fall into... */ case T_SSIR: /* software interrupt */ case T_SSIR|T_USER: /* * If this was not an AST trap, we are all done. */ if (type != (T_ASTFLT|T_USER)) { curcpu()->ci_data.cpu_ntrap--; return; } spl0(); if (l->l_pflag & LP_OWEUPC) { l->l_pflag &= ~LP_OWEUPC; ADDUPROF(l); } if (curcpu()->ci_want_resched) preempt(); goto out; case T_MMUFLT: /* kernel mode page fault */ /* * If we were doing profiling ticks or other user mode * stuff from interrupt code, Just Say No. */ onfault = pcb->pcb_onfault; if (onfault == fubail || onfault == subail) { rv = EFAULT; goto copyfault; } /* fall into ... */ case T_MMUFLT|T_USER: /* page fault */ { vaddr_t va; struct vmspace *vm = p->p_vmspace; struct vm_map *map; vm_prot_t ftype; extern struct vm_map *kernel_map; onfault = pcb->pcb_onfault; #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", p->p_pid, code, v, fp->f_pc, fp->f_sr); #endif /* * It is only a kernel address space fault iff: * 1. (type & T_USER) == 0 and * 2. pcb_onfault not set or * 3. pcb_onfault set but supervisor space data fault * The last can occur during an exec() copyin where the * argument space is lazy-allocated. */ if ((type & T_USER) == 0 && (onfault == NULL || KDFAULT(code))) map = kernel_map; else { map = vm ? &vm->vm_map : kernel_map; } if (WRFAULT(code)) ftype = VM_PROT_WRITE; else ftype = VM_PROT_READ; va = trunc_page((vaddr_t)v); if (map == kernel_map && va == 0) { printf("trap: bad kernel %s access at 0x%x\n", (ftype & VM_PROT_WRITE) ? "read/write" : "read", v); goto dopanic; } #ifdef DIAGNOSTIC if (interrupt_depth && !panicking) { printf("trap: calling uvm_fault() from interrupt!\n"); goto dopanic; } #endif pcb->pcb_onfault = NULL; rv = uvm_fault(map, va, ftype); pcb->pcb_onfault = onfault; #ifdef DEBUG if (rv && MDB_ISPID(p->p_pid)) printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", map, va, ftype, rv); #endif /* * If this was a stack access we keep track of the maximum * accessed stack size. Also, if vm_fault gets a protection * failure it is due to accessing the stack region outside * the current limit and we need to reflect that as an access * error. */ if (rv == 0) { if (map != kernel_map && (void *)va >= vm->vm_maxsaddr) uvm_grow(p, va); if (type == T_MMUFLT) { if (ucas_ras_check(&fp->F_t)) { return; } #ifdef M68040 if (cputype == CPU_68040) (void) writeback(fp, 1); #endif return; } goto out; } if (rv == EACCES) { ksi.ksi_code = SEGV_ACCERR; rv = EFAULT; } else ksi.ksi_code = SEGV_MAPERR; if (type == T_MMUFLT) { if (onfault) goto copyfault; printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", map, va, ftype, rv); printf(" type %x, code [mmu,,ssw]: %x\n", type, code); goto dopanic; } ksi.ksi_addr = (void *)v; switch (rv) { case ENOMEM: printf("UVM: pid %d (%s), uid %d killed: out of swap\n", p->p_pid, p->p_comm, l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); ksi.ksi_signo = SIGKILL; break; case EINVAL: ksi.ksi_signo = SIGBUS; ksi.ksi_code = BUS_ADRERR; break; case EACCES: ksi.ksi_signo = SIGSEGV; ksi.ksi_code = SEGV_ACCERR; break; default: ksi.ksi_signo = SIGSEGV; ksi.ksi_code = SEGV_MAPERR; break; } break; } } trapsignal(l, &ksi); if ((type & T_USER) == 0) return; out: userret(l, fp, sticks, v, 1); }
bool ASMu3Dmx::assembleL2matrices (SparseMatrix& A, StdVector& B, const IntegrandBase& integrand, bool continuous) const { const int p1 = projBasis->order(0); const int p2 = projBasis->order(1); const int p3 = projBasis->order(2); // Get Gaussian quadrature points const int ng1 = continuous ? nGauss : p1 - 1; const int ng2 = continuous ? nGauss : p2 - 1; const int ng3 = continuous ? nGauss : p3 - 1; const double* xg = GaussQuadrature::getCoord(ng1); const double* yg = GaussQuadrature::getCoord(ng2); const double* zg = GaussQuadrature::getCoord(ng3); const double* wg = continuous ? GaussQuadrature::getWeight(nGauss) : nullptr; if (!xg || !yg || !zg) return false; if (continuous && !wg) return false; size_t nnod = this->getNoProjectionNodes(); double dV = 0.0; Vectors phi(2); Matrices dNdu(2); Matrix sField, Xnod, Jac; std::vector<Go::BasisDerivs> spl1(2); std::vector<Go::BasisPts> spl0(2); // === Assembly loop over all elements in the patch ========================== LR::LRSplineVolume* geoVol; if (m_basis[geoBasis-1]->nBasisFunctions() == projBasis->nBasisFunctions()) geoVol = m_basis[geoBasis-1].get(); else geoVol = projBasis.get(); for (const LR::Element* el1 : geoVol->getAllElements()) { double uh = (el1->umin()+el1->umax())/2.0; double vh = (el1->vmin()+el1->vmax())/2.0; double wh = (el1->wmin()+el1->wmax())/2.0; std::vector<size_t> els; els.push_back(projBasis->getElementContaining(uh, vh, wh) + 1); els.push_back(m_basis[geoBasis-1]->getElementContaining(uh, vh, wh) + 1); if (continuous) { // Set up control point (nodal) coordinates for current element if (!this->getElementCoordinates(Xnod,els[1])) return false; else if ((dV = 0.25*this->getParametricVolume(els[1])) < 0.0) return false; // topology error (probably logic error) } // Compute parameter values of the Gauss points over this element RealArray gpar[3], unstrGpar[3]; this->getGaussPointParameters(gpar[0],0,ng1,els[1],xg); this->getGaussPointParameters(gpar[1],1,ng2,els[1],yg); this->getGaussPointParameters(gpar[2],2,ng3,els[1],zg); // convert to unstructred mesh representation expandTensorGrid(gpar, unstrGpar); // Evaluate the secondary solution at all integration points if (!this->evalSolution(sField,integrand,unstrGpar)) return false; // set up basis function size (for extractBasis subroutine) const LR::Element* elm = projBasis->getElement(els[0]-1); phi[0].resize(elm->nBasisFunctions()); phi[1].resize(el1->nBasisFunctions()); IntVec lmnpc; if (projBasis != m_basis[0]) { lmnpc.reserve(phi[0].size()); for (const LR::Basisfunction* f : elm->support()) lmnpc.push_back(f->getId()); } const IntVec& mnpc = projBasis == m_basis[0] ? MNPC[els[1]-1] : lmnpc; // --- Integration loop over all Gauss points in each direction ---------- Matrix eA(phi[0].size(), phi[0].size()); Vectors eB(sField.rows(), Vector(phi[0].size())); int ip = 0; for (int k = 0; k < ng3; k++) for (int j = 0; j < ng2; j++) for (int i = 0; i < ng1; i++, ip++) { if (continuous) { projBasis->computeBasis(gpar[0][i], gpar[1][j], gpar[2][k], spl1[0], els[0]-1); SplineUtils::extractBasis(spl1[0],phi[0],dNdu[0]); m_basis[geoBasis-1]->computeBasis(gpar[0][i], gpar[1][j], gpar[2][k], spl1[1], els[1]-1); SplineUtils::extractBasis(spl1[1], phi[1], dNdu[1]); } else { projBasis->computeBasis(gpar[0][i], gpar[1][j], gpar[2][k], spl0[0], els[0]-1); phi[0] = spl0[0].basisValues; } // Compute the Jacobian inverse and derivatives double dJw = 1.0; if (continuous) { dJw = dV*wg[i]*wg[j]*wg[k]*utl::Jacobian(Jac,dNdu[1],Xnod,dNdu[1],false); if (dJw == 0.0) continue; // skip singular points } // Integrate the mass matrix eA.outer_product(phi[0], phi[0], true, dJw); // Integrate the rhs vector B for (size_t r = 1; r <= sField.rows(); r++) eB[r-1].add(phi[0],sField(r,ip+1)*dJw); } for (size_t i = 0; i < eA.rows(); ++i) { for (size_t j = 0; j < eA.cols(); ++j) A(mnpc[i]+1, mnpc[j]+1) += eA(i+1,j+1); int jp = mnpc[i]+1; for (size_t r = 0; r < sField.rows(); r++, jp += nnod) B(jp) += eB[r](1+i); } } return true; }
/*ARGSUSED*/ void trap(struct frame *fp, int type, u_int code, u_int v) { extern char fubail[], subail[]; struct lwp *l; struct proc *p; ksiginfo_t ksi; int s; u_quad_t sticks; uvmexp.traps++; l = curlwp; KSI_INIT_TRAP(&ksi); ksi.ksi_trap = type & ~T_USER; p = l->l_proc; if (USERMODE(fp->f_sr)) { type |= T_USER; sticks = p->p_sticks; l->l_md.md_regs = fp->f_regs; LWP_CACHE_CREDS(l, p); } else sticks = 0; #ifdef DIAGNOSTIC if (l->l_addr == NULL) panic("trap: type 0x%x, code 0x%x, v 0x%x -- no pcb", type, code, v); #endif switch (type) { default: dopanic: printf("trap type %d, code = 0x%x, v = 0x%x\n", type, code, v); printf("%s program counter = 0x%x\n", (type & T_USER) ? "user" : "kernel", fp->f_pc); /* * Let the kernel debugger see the trap frame that * caused us to panic. This is a convenience so * one can see registers at the point of failure. */ s = splhigh(); #ifdef KGDB /* If connected, step or cont returns 1 */ if (kgdb_trap(type, (db_regs_t *)fp)) goto kgdb_cont; #endif #ifdef DDB (void)kdb_trap(type, (db_regs_t *)fp); #endif #ifdef KGDB kgdb_cont: #endif splx(s); if (panicstr) { printf("trap during panic!\n"); #ifdef DEBUG /* XXX should be a machine-dependent hook */ printf("(press a key)\n"); (void)cngetc(); #endif } regdump((struct trapframe *)fp, 128); type &= ~T_USER; if ((u_int)type < trap_types) panic(trap_type[type]); panic("trap"); case T_BUSERR: /* Kernel bus error */ if (!l->l_addr->u_pcb.pcb_onfault) goto dopanic; /* * If we have arranged to catch this fault in any of the * copy to/from user space routines, set PC to return to * indicated location and set flag informing buserror code * that it may need to clean up stack frame. */ copyfault: fp->f_stackadj = exframesize[fp->f_format]; fp->f_format = fp->f_vector = 0; fp->f_pc = (int)l->l_addr->u_pcb.pcb_onfault; return; case T_BUSERR|T_USER: /* Bus error */ case T_ADDRERR|T_USER: /* Address error */ ksi.ksi_addr = (void *)v; ksi.ksi_signo = SIGBUS; ksi.ksi_code = (type == (T_BUSERR|T_USER)) ? BUS_OBJERR : BUS_ADRERR; break; case T_ILLINST|T_USER: /* Illegal instruction fault */ case T_PRIVINST|T_USER: /* Privileged instruction fault */ ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was ILL_PRIVIN_FAULT */ ksi.ksi_signo = SIGILL; ksi.ksi_code = (type == (T_PRIVINST|T_USER)) ? ILL_PRVOPC : ILL_ILLOPC; break; /* * divde by zero, CHK/TRAPV inst */ case T_ZERODIV|T_USER: /* Divide by zero trap */ ksi.ksi_code = FPE_FLTDIV; case T_CHKINST|T_USER: /* CHK instruction trap */ case T_TRAPVINST|T_USER: /* TRAPV instruction trap */ ksi.ksi_addr = (void *)(int)fp->f_format; ksi.ksi_signo = SIGFPE; break; /* * User coprocessor violation */ case T_COPERR|T_USER: /* XXX What is a proper response here? */ ksi.ksi_signo = SIGFPE; ksi.ksi_code = FPE_FLTINV; break; /* * 6888x exceptions */ case T_FPERR|T_USER: /* * We pass along the 68881 status register which locore * stashed in code for us. Note that there is a * possibility that the bit pattern of this register * will conflict with one of the FPE_* codes defined * in signal.h. Fortunately for us, the only such * codes we use are all in the range 1-7 and the low * 3 bits of the status register are defined as 0 so * there is no clash. */ ksi.ksi_signo = SIGFPE; ksi.ksi_addr = (void *)code; break; /* * FPU faults in supervisor mode. */ case T_ILLINST: /* fnop generates this, apparently. */ case T_FPEMULI: case T_FPEMULD: { extern label_t *nofault; if (nofault) /* If we're probing. */ longjmp(nofault); if (type == T_ILLINST) printf("Kernel Illegal Instruction trap.\n"); else printf("Kernel FPU trap.\n"); goto dopanic; } /* * Unimplemented FPU instructions/datatypes. */ case T_FPEMULI|T_USER: case T_FPEMULD|T_USER: #ifdef FPU_EMULATE if (fpu_emulate(fp, &l->l_addr->u_pcb.pcb_fpregs, &ksi) == 0) ; /* XXX - Deal with tracing? (fp->f_sr & PSL_T) */ #else uprintf("pid %d killed: no floating point support.\n", p->p_pid); ksi.ksi_signo = SIGILL; ksi.ksi_code = ILL_ILLOPC; #endif break; case T_COPERR: /* Kernel coprocessor violation */ case T_FMTERR: /* Kernel format error */ case T_FMTERR|T_USER: /* User format error */ /* * The user has most likely trashed the RTE or FP state info * in the stack frame of a signal handler. */ printf("pid %d: kernel %s exception\n", p->p_pid, type==T_COPERR ? "coprocessor" : "format"); type |= T_USER; mutex_enter(p->p_lock); SIGACTION(p, SIGILL).sa_handler = SIG_DFL; sigdelset(&p->p_sigctx.ps_sigignore, SIGILL); sigdelset(&p->p_sigctx.ps_sigcatch, SIGILL); sigdelset(&l->l_sigmask, SIGILL); mutex_exit(p->p_lock); ksi.ksi_signo = SIGILL; ksi.ksi_addr = (void *)(int)fp->f_format; /* XXX was ILL_RESAD_FAULT */ ksi.ksi_code = (type == T_COPERR) ? ILL_COPROC : ILL_ILLOPC; break; /* * XXX: Trace traps are a nightmare. * * HP-UX uses trap #1 for breakpoints, * NetBSD/m68k uses trap #2, * SUN 3.x uses trap #15, * DDB and KGDB uses trap #15 (for kernel breakpoints; * handled elsewhere). * * NetBSD and HP-UX traps both get mapped by locore.s into T_TRACE. * SUN 3.x traps get passed through as T_TRAP15 and are not really * supported yet. * * XXX: We should never get kernel-mode T_TRAP15 because * XXX: locore.s now gives it special treatment. */ case T_TRAP15: /* SUN trace trap */ #ifdef DEBUG printf("unexpected kernel trace trap, type = %d\n", type); printf("program counter = 0x%x\n", fp->f_pc); #endif fp->f_sr &= ~PSL_T; ksi.ksi_signo = SIGTRAP; break; case T_TRACE|T_USER: /* user trace trap */ #ifdef COMPAT_SUNOS /* * SunOS uses Trap #2 for a "CPU cache flush". * Just flush the on-chip caches and return. */ if (p->p_emul == &emul_sunos) { ICIA(); DCIU(); return; } #endif /* FALLTHROUGH */ case T_TRACE: /* tracing a trap instruction */ case T_TRAP15|T_USER: /* SUN user trace trap */ fp->f_sr &= ~PSL_T; ksi.ksi_signo = SIGTRAP; break; case T_ASTFLT: /* System async trap, cannot happen */ goto dopanic; case T_ASTFLT|T_USER: /* User async trap. */ astpending = 0; /* * We check for software interrupts first. This is because * they are at a higher level than ASTs, and on a VAX would * interrupt the AST. We assume that if we are processing * an AST that we must be at IPL0 so we don't bother to * check. Note that we ensure that we are at least at SIR * IPL while processing the SIR. */ spl1(); /* fall into... */ case T_SSIR: /* Software interrupt */ case T_SSIR|T_USER: /* * If this was not an AST trap, we are all done. */ if (type != (T_ASTFLT|T_USER)) { uvmexp.traps--; return; } spl0(); if (l->l_pflag & LP_OWEUPC) { l->l_pflag &= ~LP_OWEUPC; ADDUPROF(l); } if (curcpu()->ci_want_resched) preempt(); goto out; case T_MMUFLT: /* Kernel mode page fault */ /* * If we were doing profiling ticks or other user mode * stuff from interrupt code, Just Say No. */ if (l->l_addr->u_pcb.pcb_onfault == fubail || l->l_addr->u_pcb.pcb_onfault == subail) goto copyfault; /* fall into... */ case T_MMUFLT|T_USER: /* page fault */ { vaddr_t va; struct vmspace *vm = p->p_vmspace; struct vm_map *map; int rv; vm_prot_t ftype; extern struct vm_map *kernel_map; #ifdef DEBUG if ((mmudebug & MDB_WBFOLLOW) || MDB_ISPID(p->p_pid)) printf("trap: T_MMUFLT pid=%d, code=%x, v=%x, pc=%x, sr=%x\n", p->p_pid, code, v, fp->f_pc, fp->f_sr); #endif /* * It is only a kernel address space fault iff: * 1. (type & T_USER) == 0 and * 2. pcb_onfault not set or * 3. pcb_onfault set but supervisor data fault * The last can occur during an exec() copyin where the * argument space is lazy-allocated. */ if (type == T_MMUFLT && (!l->l_addr->u_pcb.pcb_onfault || KDFAULT(code))) map = kernel_map; else { map = vm ? &vm->vm_map : kernel_map; if ((l->l_flag & LW_SA) && (~l->l_pflag & LP_SA_NOBLOCK)) { l->l_savp->savp_faultaddr = (vaddr_t)v; l->l_pflag |= LP_SA_PAGEFAULT; } } if (WRFAULT(code)) ftype = VM_PROT_WRITE; else ftype = VM_PROT_READ; va = trunc_page((vaddr_t)v); #ifdef DEBUG if (map == kernel_map && va == 0) { printf("trap: bad kernel access at %x\n", v); goto dopanic; } #endif rv = uvm_fault(map, va, ftype); #ifdef DEBUG if (rv && MDB_ISPID(p->p_pid)) printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", map, va, ftype, rv); #endif /* * If this was a stack access, we keep track of the maximum * accessed stack size. Also, if vm_fault gets a protection * failure, it is due to accessing the stack region outside * the current limit and we need to reflect that as an access * error. */ if (rv == 0) { if (map != kernel_map && (void *)va >= vm->vm_maxsaddr) uvm_grow(p, va); if (type == T_MMUFLT) { #if defined(M68040) if (mmutype == MMU_68040) (void)writeback(fp, 1); #endif return; } l->l_pflag &= ~LP_SA_PAGEFAULT; goto out; } if (rv == EACCES) { ksi.ksi_code = SEGV_ACCERR; rv = EFAULT; } else ksi.ksi_code = SEGV_MAPERR; if (type == T_MMUFLT) { if (l->l_addr->u_pcb.pcb_onfault) goto copyfault; printf("uvm_fault(%p, 0x%lx, 0x%x) -> 0x%x\n", map, va, ftype, rv); printf(" type %x, code [mmu,,ssw]: %x\n", type, code); goto dopanic; } l->l_pflag &= ~LP_SA_PAGEFAULT; ksi.ksi_addr = (void *)v; if (rv == ENOMEM) { printf("UVM: pid %d (%s), uid %d killed: out of swap\n", p->p_pid, p->p_comm, l->l_cred ? kauth_cred_geteuid(l->l_cred) : -1); ksi.ksi_signo = SIGKILL; } else { ksi.ksi_signo = SIGSEGV; } break; } } if (ksi.ksi_signo) trapsignal(l, &ksi); if ((type & T_USER) == 0) return; out: userret(l, fp, sticks, v, 1); }