Exemple #1
0
int askregvar(Symbol p, Symbol regs) {
	Symbol r;

	assert(p);
	if (p->sclass != REGISTER)
		return 0;
	else if (!isscalar(p->type)) {
		p->sclass = AUTO;
		return 0;
	}
	else if (p->temporary) {
		p->x.name = "?";
		return 1;
	}
	else if ((r = askreg(regs, vmask)) != NULL) {
		p->x.regnode = r->x.regnode;
		p->x.regnode->vbl = p;
		p->x.name = r->x.name;
		debug(dumpregs("(allocating %s to symbol %s)\n", p->x.name, p->name));
		return 1;
	}
	else {
		p->sclass = AUTO;
		return 0;
	}
}
Exemple #2
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		core44xx_main
 * @BRIEF		PRCM CORE menu
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_ARG
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_INTERNAL
 * @param[in]		argc: shell input argument number
 * @param[in]		argv: shell input argument(s)
 * @DESCRIPTION		PRCM CORE menu
 *//*------------------------------------------------------------------------ */
int core44xx_main(int argc, char *argv[])
{
	int ret;

	CHECK_CPU(44xx, OMAPCONF_ERR_CPU);

	if (argc == 2) {
		if (!init_done)
			core44xx_regtable_init();
		if (strcmp(argv[1], "dump") == 0) {
			ret = dumpregs(prcm_core_reg_table);
		} else if (strcmp(argv[1], "cfg") == 0) {
			ret = core44xx_config_show(stdout);
		} else if (strcmp(argv[1], "dep") == 0) {
			ret = core44xx_dependency_show(stdout);
		} else {
			help(HELP_PRCM);
			ret = OMAPCONF_ERR_ARG;
		}
	} else {
		help(HELP_PRCM);
		ret = OMAPCONF_ERR_ARG;
	}

	return ret;
}
Exemple #3
0
// lastcontinuehandler is reached, because runtime cannot handle
// current exception. lastcontinuehandler will print crash info and exit.
uint32
runtime·lastcontinuehandler(ExceptionRecord *info, Context *r, G *gp)
{
	bool crash;

	if(runtime·panicking)	// traceback already printed
		runtime·exit(2);
	runtime·panicking = 1;

	runtime·printf("Exception %x %p %p %p\n", info->ExceptionCode,
		(uintptr)info->ExceptionInformation[0], (uintptr)info->ExceptionInformation[1], (uintptr)r->Eip);

	runtime·printf("PC=%x\n", r->Eip);
	if(g->m->lockedg != nil && g->m->ncgo > 0 && gp == g->m->g0) {
		runtime·printf("signal arrived during cgo execution\n");
		gp = g->m->lockedg;
	}
	runtime·printf("\n");

	if(runtime·gotraceback(&crash)){
		runtime·traceback(r->Eip, r->Esp, 0, gp);
		runtime·tracebackothers(gp);
		runtime·dumpregs(r);
	}
	
	if(crash)
		runtime·crash();

	runtime·exit(2);
	return 0; // not reached
}
Exemple #4
0
static void
profintr(Ureg *ur, void*)
{
	OstmrReg *ost = OSTMRREG;
	int t;

	if((ost->osmr[3] - ost->oscr) < 2*CLOCKFREQ) {
		/* less than 2 seconds before reset, say something */
		setpanic();
		clockpoll();
		dumpregs(ur);
		panic("Watchdog timer will expire");
	}

	/* advance the profile clock tick */
	ost->osmr[2] += timer_incr[2];
	ost->ossr = (1 << 2); 			/* Clear the SR */
	t = 1;
	while((ost->osmr[2] - ost->oscr) > 0x80000000) {
		ost->osmr[2] += timer_incr[2];
		t++;
	}
	if(prof_fcn)
		prof_fcn(ur, t);
}
uint32
runtime·sighandler(ExceptionRecord *info, Context *r, G *gp)
{
	uintptr *sp;

	switch(info->ExceptionCode) {
	case EXCEPTION_BREAKPOINT:
		r->Eip--;	// because 8l generates 2 bytes for INT3
		return 1;
	}

	if(gp != nil && runtime·issigpanic(info->ExceptionCode)) {
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp->sig = info->ExceptionCode;
		gp->sigcode0 = info->ExceptionInformation[0];
		gp->sigcode1 = info->ExceptionInformation[1];
		gp->sigpc = r->Eip;

		// Only push runtime·sigpanic if r->eip != 0.
		// If r->eip == 0, probably panicked because of a
		// call to a nil func.  Not pushing that onto sp will
		// make the trace look like a call to runtime·sigpanic instead.
		// (Otherwise the trace will end at runtime·sigpanic and we
		// won't get to see who faulted.)
		if(r->Eip != 0) {
			sp = (uintptr*)r->Esp;
			*--sp = r->Eip;
			r->Esp = (uintptr)sp;
		}
		r->Eip = (uintptr)runtime·sigpanic;
		return 0;
	}

	if(runtime·panicking)	// traceback already printed
		runtime·exit(2);
	runtime·panicking = 1;

	runtime·printf("Exception %x %p %p\n", info->ExceptionCode,
		info->ExceptionInformation[0], info->ExceptionInformation[1]);

	runtime·printf("PC=%x\n", r->Eip);
	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
		runtime·printf("signal arrived during cgo execution\n");
		gp = m->lockedg;
	}
	runtime·printf("\n");

	if(runtime·gotraceback()){
		runtime·traceback((void*)r->Eip, (void*)r->Esp, 0, gp);
		runtime·tracebackothers(gp);
		runtime·dumpregs(r);
	}

	runtime·exit(2);
	return 0;
}
Exemple #6
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		core44xx_dump
 * @BRIEF		dump PRCM CORE registers
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 * @DESCRIPTION		dump PRCM CORE registers
 *//*------------------------------------------------------------------------ */
int core44xx_dump(void)
{
	CHECK_CPU(44xx, OMAPCONF_ERR_CPU);

	if (!init_done)
		core44xx_regtable_init();

	return dumpregs(prcm_core_reg_table);
}
Exemple #7
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		wkup44xx_dump
 * @BRIEF		dump PRCM WKUP registers
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_REG_ACCESS
 *			OMAPCONF_ERR_CPU
 * @DESCRIPTION		dump PRCM WKUP registers
 *//*------------------------------------------------------------------------ */
int wkup44xx_dump(void)
{
	CHECK_CPU(44xx, OMAPCONF_ERR_ARG);

	if (!init_done)
		wkup44xx_regtable_init();

	return dumpregs(prcm_wkup_reg_table);
}
Exemple #8
0
static int mxc_hdmi_codec_prepare(struct snd_pcm_substream *substream,
				  struct snd_soc_dai *dai)
{
	struct snd_pcm_runtime *runtime = substream->runtime;

	hdmi_set_layout(runtime->channels);
	hdmi_set_sample_rate(runtime->rate);
	dumpregs();

	return 0;
}
Exemple #9
0
static void
faultarm(Ureg *ureg)
{
	char buf[ERRMAX];

	sprint(buf, "sys: trap: fault pc=%8.8lux", (ulong)ureg->pc);
	if(0){
		iprint("%s\n", buf);
		dumpregs(ureg);
	}
	disfault(ureg, buf);
}
Exemple #10
0
static void ralloc(Node p) {
	int i;
	unsigned mask[2];

	mask[0] = tmask[0];
	mask[1] = tmask[1];
	assert(p);
	debug(fprint(stderr, "(rallocing %x)\n", p));
	for (i = 0; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
		Node kid = p->x.kids[i];
		Symbol r = kid->syms[RX];
		assert(r && kid->x.registered);
		if (r->sclass != REGISTER && r->x.lastuse == kid)
			putreg(r);
	}
	if (!p->x.registered && NeedsReg[opindex(p->op)]
	&& (*IR->x.rmap)(opkind(p->op))) {
		Symbol sym = p->syms[RX], set = sym;
		assert(sym);
		if (sym->temporary)
			set = (*IR->x.rmap)(opkind(p->op));
		assert(set);
		if (set->sclass != REGISTER) {
			Symbol r;
			if (*IR->x._templates[getrule(p, p->x.inst)] == '?')
				for (i = 1; i < NELEMS(p->x.kids) && p->x.kids[i]; i++) {
					Symbol r = p->x.kids[i]->syms[RX];
					assert(p->x.kids[i]->x.registered);
					assert(r && r->x.regnode);
					assert(sym->x.wildcard || sym != r);
					mask[r->x.regnode->set] &= ~r->x.regnode->mask;
				}
			r = getreg(set, mask, p);
			if (sym->temporary) {
				Node q;
				r->x.lastuse = sym->x.lastuse;
				for (q = sym->x.lastuse; q; q = q->x.prevuse) {
					q->syms[RX] = r;
					q->x.registered = 1;
					if (sym->u.t.cse && q->x.copy)
						q->x.equatable = 1;
				}
			} else {
				p->syms[RX] = r;
				r->x.lastuse = p;
			}
			debug(dumpregs("(allocating %s to node %x)\n", r->x.name, (char *) p));
		}
	}
	p->x.registered = 1;
	(*IR->x.clobber)(p);
}
Exemple #11
0
void fatal(const char *format, ...)
{
    va_list ap;
    va_start(ap, format);
    vprintf(format, ap);
    va_end(ap);
    closeide();
    fflush(stdout);
    dumppic();
    dumpregs();
    fflush(stdout);
    exit(-1);
}
int main(int argc, char **argv)
{
	if (argc < 2) { fprintf(stderr, "Need spi device\n"); return 1; }

	int fd = open(argv[1], O_RDWR);
	if (fd < 0) { perror("open"); return 1;	}

	dumpstat(argv[1], fd);

	dumpregs(fd);

	close(fd);
}
Exemple #13
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		stm_dump_regs
 * @BRIEF		dump STM registers
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_NOT_AVAILABLE
 * @DESCRIPTION		dump STM registers
 *//*------------------------------------------------------------------------ */
int stm_dump_regs(void)
{
	if (!emu44xx_is_enabled()) {
		printf("stm_dump_regs(): "
			"trying to enable ETB but EMU domain OFF!!!\n");
		return OMAPCONF_ERR_NOT_AVAILABLE;
	}

	if (!stm_is_claimed()) {
		printf("stm_dump_regs(): STM not claimed!\n");
		return OMAPCONF_ERR_INTERNAL;
	}

	return dumpregs((reg_table *) omap4_stm_reg_table);
}
Exemple #14
0
void closepc()
{
    atapi->exit();
//        ioctl_close();
    dumppic();
//        output=7;
//        setpitclock(clocks[0][0][0]);
//        while (1) runpc();
    savedisc(0);
    savedisc(1);
    dumpregs();
    closevideo();
    device_close_all();
    midi_close();
}
Exemple #15
0
static void
faultarm(Ureg *ureg, ulong fsr, uintptr addr)
{
	int user, insyscall, read;
	static char buf[ERRMAX];
	char *err;

	read = (fsr & (1<<11)) == 0;
	user = userureg(ureg);
	if(!user){
		if(addr >= USTKTOP || up == nil)
			_dumpstack(ureg);
		if(addr >= USTKTOP)
			panic("kernel fault: bad address pc=%#.8lux addr=%#.8lux fsr=%#.8lux", ureg->pc, addr, fsr);
		if(up == nil)
			panic("kernel fault: no user process pc=%#.8lux addr=%#.8lux fsr=%#.8lux", ureg->pc, addr, fsr);
	}
	if(up == nil)
		panic("user fault: up=nil pc=%#.8lux addr=%#.8lux fsr=%#.8lux", ureg->pc, addr, fsr);

	insyscall = up->insyscall;
	up->insyscall = 1;
	switch(fsr & 0x1F){
	case 0x05:	/* translation fault L1 */
	case 0x07:	/* translation fault L2 */
	case 0x03:	/* access flag fault L1 */
	case 0x06:	/* access flag fault L2 */
	case 0x09:	/* domain fault L1 */
	case 0x0B:	/* domain fault L2 */
	case 0x0D:	/* permission fault L1 */
	case 0x0F:	/* permission fault L2 */
		if(fault(addr, read) == 0)
			break;
		/* wet floor */
	default:
		err = faulterr[fsr & 0x1F];
		if(err == nil)
			err = "fault";
		if(!user){
			dumpregs(ureg);
			_dumpstack(ureg);
			panic("kernel %s: pc=%#.8lux addr=%#.8lux fsr=%#.8lux", err, ureg->pc, addr, fsr);
		}
		sprint(buf, "sys: trap: %s %s addr=%#.8lux", err, read ? "read" : "write", addr);
		postnote(up, 1, buf, NDebug);
	}
	up->insyscall = insyscall;
}
Exemple #16
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		sr44xx_dump
 * @BRIEF		dump SR PRCM registers
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_CPU
 *			OMAPCONF_ERR_REG_ACCESS
 * @DESCRIPTION		dump SR PRCM registers
 *//*------------------------------------------------------------------------ */
int sr44xx_dump(void)
{
	unsigned int ret;

	if (!cpu_is_omap44xx())
		return OMAPCONF_ERR_CPU;

	if (!init_done)
		sr44xx_regtable_init();

	if (mod44xx_is_accessible(OMAP4_SMARTREFLEX_MPU) != 1) {
		printf("SR_MPU not accessible.\n");
	} else {
		ret = dumpregs(prcm_sr_mpu_reg_table);
		if (ret != 0)
			return ret;
		ret = dumpregs(prcm_sr_vp_mpu_reg_table);
		if (ret != 0)
			return ret;
	}

	if (mod44xx_is_accessible(OMAP4_SMARTREFLEX_IVA) != 1) {
		printf("SR_IVA not accessible.\n");
	} else {
		ret = dumpregs(prcm_sr_iva_reg_table);
		if (ret != 0)
			return ret;
		ret = dumpregs(prcm_sr_vp_iva_reg_table);
		if (ret != 0)
			return ret;
	}

	if (mod44xx_is_accessible(OMAP4_SMARTREFLEX_CORE) != 1) {
		printf("SR_CORE not accessible.\n");
	} else {
		ret = dumpregs(prcm_sr_core_reg_table);
		if (ret != 0)
			return ret;
		ret = dumpregs(prcm_sr_vp_core_reg_table);
		if (ret != 0)
			return ret;
	}

	return dumpregs(prcm_sr_vc_reg_table);
}
Exemple #17
0
/* ------------------------------------------------------------------------*//**
 * @FUNCTION		stm_atb_capture_enable
 * @BRIEF		enable STM trace to be captured in ETB via ATB
 * @RETURNS		0 in case of success
 *			OMAPCONF_ERR_NOT_AVAILABLE
 * @DESCRIPTION		enable STM trace to be captured in ETB via ATB
 *			NB: make sure EMU domain is ON before calling this
 *			function.
 *//*------------------------------------------------------------------------ */
int stm_atb_capture_enable(void)
{
	if (!emu44xx_is_enabled()) {
		printf("stm_atb_capture_enable(): "
			"trying to enable ETB but EMU domain OFF!!!\n");
		return OMAPCONF_ERR_NOT_AVAILABLE;
	}
	if (!stm_is_claimed()) {
		printf("stm_atb_capture_enable(): STM not claimed!\n");
		return OMAPCONF_ERR_INTERNAL;
	}

	mem_write(OMAP4430_ATB_CONFIG, 0x00010000);

	#ifdef STM_OMAP4_DEBUG
	printf("stm_atb_capture_enable(): ATB capture enabled.\n");
	dumpregs((reg_table *) omap4_stm_reg_table);
	#endif

	return 0;
}
Exemple #18
0
void
sighandler(int32 sig, Siginfo *info, void *context)
{
	Ucontext *uc;
	Mcontext *mc;
	Regs *r;

	if(sigtab[sig].flags & SigQueue) {
		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
			return;
		exit(2);	// SIGINT, SIGTERM, etc
	}

	if(panicking)	// traceback already printed
		exit(2);
	panicking = 1;

	if(sig < 0 || sig >= NSIG){
		printf("Signal %d\n", sig);
	}else{
		printf("%s\n", sigtab[sig].name);
	}

	uc = context;
	mc = uc->uc_mcontext;
	r = &mc->ss;

	printf("Faulting address: %p\n", info->si_addr);
	printf("pc: %X\n", r->rip);
	printf("\n");

	if(gotraceback()){
		traceback((void*)r->rip, (void*)r->rsp, (void*)r->r15);
		tracebackothers((void*)r->r15);
		dumpregs(r);
	}

	breakpoint();
	exit(2);
}
Exemple #19
0
static void
dumpregs_v8p(const prgregset_t reg, const prxregset_t *xreg, int is64)
{
	static const uint32_t zero[8] = { 0 };
	int gr, xr, cols = 2;
	uint64_t xval;

	if (memcmp(xreg->pr_un.pr_v8p.pr_xg, zero, sizeof (zero)) == 0 &&
	    memcmp(xreg->pr_un.pr_v8p.pr_xo, zero, sizeof (zero)) == 0) {
		dumpregs(reg, is64);
		return;
	}

	for (gr = R_G0, xr = XR_G0; gr <= R_G7; gr++, xr++) {
		xval = (uint64_t)xreg->pr_un.pr_v8p.pr_xg[xr] << 32 |
		    (uint64_t)(uint32_t)reg[gr];
		(void) printf("  %s = 0x%.16" PRIX64, regname[gr], xval);
		if ((gr + 1) % cols == 0)
			(void) putchar('\n');
	}

	for (gr = R_O0, xr = XR_O0; gr <= R_O7; gr++, xr++) {
		xval = (uint64_t)xreg->pr_un.pr_v8p.pr_xo[xr] << 32 |
		    (uint64_t)(uint32_t)reg[gr];
		(void) printf("  %s = 0x%.16" PRIX64, regname[gr], xval);
		if ((gr + 1) % cols == 0)
			(void) putchar('\n');
	}

	for (gr = R_L0; gr < NPRGREG; gr++) {
		(void) printf("  %s =         0x%.8lX",
		    regname[gr], (long)reg[gr]);
		if ((gr + 1) % cols == 0)
			(void) putchar('\n');
	}

	if (gr % cols != 0)
		(void) putchar('\n');
}
Exemple #20
0
static void
fault386(Ureg* ureg, void*)
{
	ulong addr;
	int read, user, n, insyscall;
	char buf[ERRMAX];

	addr = getcr2();
	read = !(ureg->ecode & 2);

	user = (ureg->cs & 0xFFFF) == UESEL;
	if(!user){
		if(vmapsync(addr))
			return;
		if(addr >= USTKTOP)
			panic("kernel fault: bad address pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
		if(up == nil)
			panic("kernel fault: no user process pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);
	}
	if(up == nil)
		panic("user fault: up=0 pc=0x%.8lux addr=0x%.8lux", ureg->pc, addr);

	insyscall = up->insyscall;
	up->insyscall = 1;
	n = fault(addr, read);
	if(n < 0){
		if(!user){
			dumpregs(ureg);
			panic("fault: 0x%lux", addr);
		}
		checkpages();
		checkfault(addr, ureg->pc);
		sprint(buf, "sys: trap: fault %s addr=0x%lux",
			read ? "read" : "write", addr);
		postnote(up, 1, buf, NDebug);
	}
	up->insyscall = insyscall;
}
Exemple #21
0
void
sighandler(int32 sig, Siginfo* info, void* context)
{
	Ucontext *uc;
	Mcontext *mc;

	if(sigtab[sig].flags & SigQueue) {
		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
			return;
		exit(2);	// SIGINT, SIGTERM, etc
	}

	if(panicking)	// traceback already printed
		exit(2);
	panicking = 1;

	uc = context;
	mc = &uc->uc_mcontext;

	if(sig < 0 || sig >= NSIG)
		printf("Signal %d\n", sig);
	else
		printf("%s\n", sigtab[sig].name);

	printf("Faulting address: %p\n", info->si_addr);
	printf("PC=%X\n", mc->mc_eip);
	printf("\n");

	if(gotraceback()){
		traceback((void*)mc->mc_eip, (void*)mc->mc_esp, m->curg);
		tracebackothers(m->curg);
		dumpregs(mc);
	}

	breakpoint();
	exit(2);
}
Exemple #22
0
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
	Ucontext *uc;
	Sigcontext *r;
	SigTab *t;

	uc = context;
	r = &uc->uc_mcontext;

	if(sig == SIGPROF) {
		runtime·sigprof((uint8*)r->arm_pc, (uint8*)r->arm_sp, (uint8*)r->arm_lr, gp);
		return;
	}

	t = &runtime·sigtab[sig];
	if(info->si_code != SI_USER && (t->flags & SigPanic)) {
		if(gp == nil)
			goto Throw;
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp->sig = sig;
		gp->sigcode0 = info->si_code;
		gp->sigcode1 = r->fault_address;
		gp->sigpc = r->arm_pc;

		// If this is a leaf function, we do smash LR,
		// but we're not going back there anyway.
		// Don't bother smashing if r->arm_pc is 0,
		// which is probably a call to a nil func: the
		// old link register is more useful in the stack trace.
		if(r->arm_pc != 0)
			r->arm_lr = r->arm_pc;
		// In case we are panicking from external C code
		r->arm_r10 = (uintptr)gp;
		r->arm_r9 = (uintptr)m;
		r->arm_pc = (uintptr)runtime·sigpanic;
		return;
	}

	if(info->si_code == SI_USER || (t->flags & SigNotify))
		if(runtime·sigsend(sig))
			return;
	if(t->flags & SigKill)
		runtime·exit(2);
	if(!(t->flags & SigThrow))
		return;

Throw:
	if(runtime·panicking)	// traceback already printed
		runtime·exit(2);
	runtime·panicking = 1;

	if(sig < 0 || sig >= NSIG)
		runtime·printf("Signal %d\n", sig);
	else
		runtime·printf("%s\n", runtime·sigtab[sig].name);

	runtime·printf("PC=%x\n", r->arm_pc);
	runtime·printf("\n");

	if(runtime·gotraceback()){
		runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, gp);
		runtime·tracebackothers(gp);
		runtime·printf("\n");
		runtime·dumpregs(r);
	}

//	breakpoint();
	runtime·exit(2);
}
Exemple #23
0
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
    Ucontext *uc;
    Sigcontext *r;
    SigTab *t;

    uc = context;
    r = &uc->uc_mcontext;

    if(sig == SIGPROF) {
        runtime·sigprof((uint8*)r->arm_pc, (uint8*)r->arm_sp, (uint8*)r->arm_lr, gp);
        return;
    }

    t = &runtime·sigtab[sig];
    if(info->si_code != SI_USER && (t->flags & SigPanic)) {
        if(gp == nil || gp == m->g0)
            goto Throw;
        // Make it look like a call to the signal func.
        // Have to pass arguments out of band since
        // augmenting the stack frame would break
        // the unwinding code.
        gp->sig = sig;
        gp->sigcode0 = info->si_code;
        gp->sigcode1 = r->fault_address;
        gp->sigpc = r->arm_pc;

        // We arrange lr, and pc to pretend the panicking
        // function calls sigpanic directly.
        // Always save LR to stack so that panics in leaf
        // functions are correctly handled. This smashes
        // the stack frame but we're not going back there
        // anyway.
        r->arm_sp -= 4;
        *(uint32 *)r->arm_sp = r->arm_lr;
        // Don't bother saving PC if it's zero, which is
        // probably a call to a nil func: the old link register
        // is more useful in the stack trace.
        if(r->arm_pc != 0)
            r->arm_lr = r->arm_pc;
        // In case we are panicking from external C code
        r->arm_r10 = (uintptr)gp;
        r->arm_r9 = (uintptr)m;
        r->arm_pc = (uintptr)runtime·sigpanic;
        return;
    }

    if(info->si_code == SI_USER || (t->flags & SigNotify))
        if(runtime·sigsend(sig))
            return;
    if(t->flags & SigKill)
        runtime·exit(2);
    if(!(t->flags & SigThrow))
        return;

Throw:
    if(runtime·panicking)	// traceback already printed
        runtime·exit(2);
    runtime·panicking = 1;

    if(sig < 0 || sig >= NSIG)
        runtime·printf("Signal %d\n", sig);
    else
        runtime·printf("%s\n", runtime·sigtab[sig].name);

    runtime·printf("PC=%x\n", r->arm_pc);
    if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
        runtime·printf("signal arrived during cgo execution\n");
        gp = m->lockedg;
    }
    runtime·printf("\n");

    if(runtime·gotraceback()) {
        runtime·traceback((void*)r->arm_pc, (void*)r->arm_sp, (void*)r->arm_lr, gp);
        runtime·tracebackothers(gp);
        runtime·printf("\n");
        runtime·dumpregs(r);
    }

//	breakpoint();
    runtime·exit(2);
}
Exemple #24
0
/*
 * Entered in AP core context, upon traps (system calls go through acsyscall)
 * using up->dbgreg means cores MUST be homogeneous.
 *
 * BUG: We should setup some trapenable() mechanism for the AC,
 * so that code like fpu.c could arrange for handlers specific for
 * the AC, instead of doint that by hand here.
 *
 * All interrupts are masked while in the "kernel"
 */
void
actrap(Ureg *u)
{
	panic("actrap");
#if 0
	char *n;
	ACVctl *v;

	n = nil;

	_pmcupdate(m);
	if(m->proc != nil){
		m->proc->nactrap++;
		m->proc->actime1 = fastticks(nil);
	}
	if(u->type < nelem(acvctl)){
		v = acvctl[u->type];
		if(v != nil){
			DBG("actrap: cpu%d: %ulld\n", machp()->machno, u->type);
			n = v->f(u, v->a);
			if(n != nil)
				goto Post;
			return;
		}
	}
	switch(u->type){
	case IdtDF:
		print("AC: double fault\n");
		dumpregs(u);
		ndnr();
	case IdtIPI:
		m->intr++;
		DBG("actrap: cpu%d: IPI\n", machp()->machno);
		apiceoi(IdtIPI);
		break;
	case IdtTIMER:
		apiceoi(IdtTIMER);
		panic("timer interrupt in an AC");
		break;
	case IdtPF:
		/* this case is here for debug only */
		m->pfault++;
		DBG("actrap: cpu%d: PF cr2 %#ullx\n", machp()->machno, cr2get());
		break;
	default:
		print("actrap: cpu%d: %ulld\n", machp()->machno, u->type);
	}
Post:
	m->icc->rc = ICCTRAP;
	m->cr2 = cr2get();
	memmove(m->proc->dbgreg, u, sizeof *u);
	m->icc->note = n;
	fpuprocsave(m->proc);
	_pmcupdate(m);
	mfence();
	m->icc->fn = nil;
	ready(m->proc);

	mwait(&m->icc->fn);

	if(m->icc->flushtlb)
		acmmuswitch();
	if(m->icc->fn != actrapret)
		acsched();
	DBG("actrap: ret\n");
	memmove(u, m->proc->dbgreg, sizeof *u);
	if(m->proc)
		m->proc->actime += fastticks2us(fastticks(nil) - m->proc->actime1);
#endif
}
void
runtime·sighandler(int32 sig, Siginfo *info, void *context, G *gp)
{
	Ucontext *uc;
	Mcontext *mc;
	Sigcontext *r;
	uintptr *sp;

	uc = context;
	mc = &uc->uc_mcontext;
	r = (Sigcontext*)mc;	// same layout, more conveient names

	if(sig == SIGPROF) {
		runtime·sigprof((uint8*)r->rip, (uint8*)r->rsp, nil, gp);
		return;
	}

	if(gp != nil && (runtime·sigtab[sig].flags & SigPanic)) {
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp->sig = sig;
		gp->sigcode0 = info->si_code;
		gp->sigcode1 = ((uintptr*)info)[2];
		gp->sigpc = r->rip;

		// Only push runtime·sigpanic if r->rip != 0.
		// If r->rip == 0, probably panicked because of a
		// call to a nil func.  Not pushing that onto sp will
		// make the trace look like a call to runtime·sigpanic instead.
		// (Otherwise the trace will end at runtime·sigpanic and we
		// won't get to see who faulted.)
		if(r->rip != 0) {
			sp = (uintptr*)r->rsp;
			*--sp = r->rip;
			r->rsp = (uintptr)sp;
		}
		r->rip = (uintptr)runtime·sigpanic;
		return;
	}

	if(runtime·sigtab[sig].flags & SigQueue) {
		if(runtime·sigsend(sig) || (runtime·sigtab[sig].flags & SigIgnore))
			return;
		runtime·exit(2);	// SIGINT, SIGTERM, etc
	}

	if(runtime·panicking)	// traceback already printed
		runtime·exit(2);
	runtime·panicking = 1;

	if(sig < 0 || sig >= NSIG)
		runtime·printf("Signal %d\n", sig);
	else
		runtime·printf("%s\n", runtime·sigtab[sig].name);

	runtime·printf("PC=%X\n", r->rip);
	runtime·printf("\n");

	if(runtime·gotraceback()){
		runtime·traceback((void*)r->rip, (void*)r->rsp, 0, gp);
		runtime·tracebackothers(gp);
		runtime·dumpregs(r);
	}

	runtime·exit(2);
}
Exemple #26
0
void
runtime·sighandler(int32 sig, Siginfo *info, void *ctxt, G *gp)
{
	uintptr *sp;
	SigTab *t;
	bool crash;

	if(sig == SIGPROF) {
		if(gp != m->g0 && gp != m->gsignal)
			runtime·sigprof((byte*)SIG_RIP(info, ctxt), (byte*)SIG_RSP(info, ctxt), nil, gp);
		return;
	}

	t = &runtime·sigtab[sig];
	if(SIG_CODE0(info, ctxt) != SI_USER && (t->flags & SigPanic)) {
		if(gp == nil || gp == m->g0)
			goto Throw;

		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp->sig = sig;
		gp->sigcode0 = SIG_CODE0(info, ctxt);
		gp->sigcode1 = SIG_CODE1(info, ctxt);
		gp->sigpc = SIG_RIP(info, ctxt);

#ifdef GOOS_darwin
		// Work around Leopard bug that doesn't set FPE_INTDIV.
		// Look at instruction to see if it is a divide.
		// Not necessary in Snow Leopard (si_code will be != 0).
		if(sig == SIGFPE && gp->sigcode0 == 0) {
			byte *pc;
			pc = (byte*)gp->sigpc;
			if((pc[0]&0xF0) == 0x40)	// 64-bit REX prefix
				pc++;
			else if(pc[0] == 0x66)	// 16-bit instruction prefix
				pc++;
			if(pc[0] == 0xF6 || pc[0] == 0xF7)
				gp->sigcode0 = FPE_INTDIV;
		}
#endif

		// Only push runtime·sigpanic if rip != 0.
		// If rip == 0, probably panicked because of a
		// call to a nil func.  Not pushing that onto sp will
		// make the trace look like a call to runtime·sigpanic instead.
		// (Otherwise the trace will end at runtime·sigpanic and we
		// won't get to see who faulted.)
		if(SIG_RIP(info, ctxt) != 0) {
			sp = (uintptr*)SIG_RSP(info, ctxt);
			*--sp = SIG_RIP(info, ctxt);
			SIG_RSP(info, ctxt) = (uintptr)sp;
		}
		SIG_RIP(info, ctxt) = (uintptr)runtime·sigpanic;
		return;
	}

	if(SIG_CODE0(info, ctxt) == SI_USER || (t->flags & SigNotify))
		if(runtime·sigsend(sig))
			return;
	if(t->flags & SigKill)
		runtime·exit(2);
	if(!(t->flags & SigThrow))
		return;

Throw:
	m->throwing = 1;
	m->caughtsig = gp;
	runtime·startpanic();

	if(sig < 0 || sig >= NSIG)
		runtime·printf("Signal %d\n", sig);
	else
		runtime·printf("%s\n", runtime·sigtab[sig].name);

	runtime·printf("PC=%X\n", SIG_RIP(info, ctxt));
	if(m->lockedg != nil && m->ncgo > 0 && gp == m->g0) {
		runtime·printf("signal arrived during cgo execution\n");
		gp = m->lockedg;
	}
	runtime·printf("\n");

	if(runtime·gotraceback(&crash)){
		runtime·traceback(SIG_RIP(info, ctxt), SIG_RSP(info, ctxt), 0, gp);
		runtime·tracebackothers(gp);
		runtime·printf("\n");
		runtime·dumpregs(info, ctxt);
	}
	
	if(crash)
		runtime·crash();

	runtime·exit(2);
}
Exemple #27
0
void
sighandler(int32 sig, Siginfo *info, void *context)
{
	Ucontext *uc;
	Mcontext *mc;
	Regs *r;
	G *gp;
	uintptr *sp;
	byte *pc;

	uc = context;
	mc = uc->uc_mcontext;
	r = &mc->ss;

	if((gp = m->curg) != nil && (sigtab[sig].flags & SigPanic)) {
		// Work around Leopard bug that doesn't set FPE_INTDIV.
		// Look at instruction to see if it is a divide.
		// Not necessary in Snow Leopard (si_code will be != 0).
		if(sig == SIGFPE && info->si_code == 0) {
			pc = (byte*)r->rip;
			if((pc[0]&0xF0) == 0x40)	// 64-bit REX prefix
				pc++;
			if(pc[0] == 0xF7)
				info->si_code = FPE_INTDIV;
		}
		
		// Make it look like a call to the signal func.
		// Have to pass arguments out of band since
		// augmenting the stack frame would break
		// the unwinding code.
		gp->sig = sig;
		gp->sigcode0 = info->si_code;
		gp->sigcode1 = (uintptr)info->si_addr;
		
		// Only push sigpanic if r->rip != 0.
		// If r->rip == 0, probably panicked because of a
		// call to a nil func.  Not pushing that onto sp will
		// make the trace look like a call to sigpanic instead.
		// (Otherwise the trace will end at sigpanic and we
		// won't get to see who faulted.)
		if(r->rip != 0) {
			sp = (uintptr*)r->rsp;
			*--sp = r->rip;
			r->rsp = (uintptr)sp;
		}
		r->rip = (uintptr)sigpanic;
		return;
	}

	if(sigtab[sig].flags & SigQueue) {
		if(sigsend(sig) || (sigtab[sig].flags & SigIgnore))
			return;
		exit(2);	// SIGINT, SIGTERM, etc
	}

	if(panicking)	// traceback already printed
		exit(2);
	panicking = 1;

	if(sig < 0 || sig >= NSIG){
		printf("Signal %d\n", sig);
	}else{
		printf("%s\n", sigtab[sig].name);
	}

	printf("pc: %X\n", r->rip);
	printf("\n");

	if(gotraceback()){
		traceback((void*)r->rip, (void*)r->rsp, 0, (void*)r->r15);
		tracebackothers((void*)r->r15);
		dumpregs(r);
	}

	breakpoint();
	exit(2);
}
Exemple #28
0
void callback8271()
{
        int diff=i8271.params[0]-i8271.curtrack[curdrive];
        fdctime=0;
//        printf("Callback 8271 - command %02X\n",i8271.command);
        switch (i8271.command)
        {
                case 0x0B: /*Write*/
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
                        disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        
                        i8271.status=0x8C;
                        i8271.result=0;
                        NMI8271();
                        return;
                }
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                i8271.cursector++;
                disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                i8271.status=0x8C;
                i8271.result=0;
                NMI8271();
                break;

                case 0x13: /*Read*/
                case 0x1F: /*Verify*/
                if (!i8271.phase)
                {
//                        printf("Seek to %i\n",i8271.params[0]);
                        i8271.curtrack[curdrive]=i8271.params[0];
//                        i8271.realtrack+=diff;
//                        disc_seek(0,i8271.realtrack);
//                        printf("Re-seeking - track now %i %i\n",i8271.curtrack,i8271.realtrack);
                        disc_readsector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        return;
                }
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                i8271.cursector++;
                disc_readsector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                break;
                
                case 0x1B: /*Read ID*/
//                printf("Read ID callback %i\n",i8271.phase);
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
//                        i8271.realtrack+=diff;
//                        disc_seek(0,i8271.realtrack);
                        disc_readaddress(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;
                        return;
                }
//                printf("Read ID track %i %i\n",i8271.params[0],i8271.sectorsleft);
                i8271.sectorsleft--;
                if (!i8271.sectorsleft)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
//                        printf("8271 : ID read done!\n");
                        setspindown8271();
                        return;
                }
                i8271.cursector++;
                disc_readaddress(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                byte=0;
                break;

                case 0x23: /*Format*/
                if (!i8271.phase)
                {
                        i8271.curtrack[curdrive]=i8271.params[0];
                        disc_writesector(curdrive,i8271.cursector,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                        i8271.phase=1;

                        i8271.status=0x8C;
                        i8271.result=0;
                        NMI8271();
                        return;
                }
                if (i8271.phase==2)
                {
                        i8271.status=0x18;
                        i8271.result=0;
                        NMI8271();
                        setspindown8271();
                        verify8271=0;
                        return;
                }
                disc_format(curdrive,i8271.params[0],(i8271.drvout&0x20)?1:0,0);
                i8271.phase=2;
                break;

                case 0x29: /*Seek*/
                i8271.curtrack[curdrive]=i8271.params[0];
//                i8271.realtrack+=diff;
                i8271.status=0x18;
                i8271.result=0;
                NMI8271();
//                disc_seek(0,i8271.realtrack);
//                printf("Seek done!\n");
                setspindown8271();
                break;
                
                case 0xFF: break;
                
                default: break;
                printf("Unknown 8271 command %02X 3\n",i8271.command);
                dumpregs();
                exit(-1);
        }
}
Exemple #29
0
/*
 *  All traps come here.  It is slower to have all traps call trap()
 *  rather than directly vectoring the handler.  However, this avoids a
 *  lot of code duplication and possible bugs.  The only exception is
 *  VectorSYSCALL.
 *  Trap is called with interrupts disabled via interrupt-gates.
 */
void
trap(Ureg* ureg)
{
	int clockintr, vno, user;
	// cache the previous vno to see what might be causing
	// trouble
	static int lastvno;
	vno = ureg->type;
	uint64_t gsbase = rdmsr(GSbase);
	//if (sce > scx) iprint("====================");
	if (vno == 8) {
		iprint("Lstar is %p\n", (void *)rdmsr(Lstar));
		iprint("GSbase is %p\n", (void *)gsbase);
		iprint("ire %d irx %d sce %d scx %d lastvno %d\n", 
			ire, irx, sce, scx, lastvno);
		iprint("irxe %d \n",
			irxe);
		die("8");
	}
	lastvno = vno;
	if (gsbase < 1ULL<<63)
		die("bogus gsbase");
	Mach *m = machp();
	char buf[ERRMAX];
	Vctl *ctl, *v;

	if (0 && m && m->externup && m->externup->pid == 6) {
		//iprint("type %x\n", ureg->type);
		if (ureg->type != 0x49)
			die("6\n");
	}
	m->perf.intrts = perfticks();
	user = userureg(ureg);
	if(user && (m->nixtype == NIXTC)){
		m->externup->dbgreg = ureg;
		cycles(&m->externup->kentry);
	}

	clockintr = 0;

	//_pmcupdate(m);

	if(ctl = vctl[vno]){
		if(ctl->isintr){
			m->intr++;
			if(vno >= VectorPIC && vno != VectorSYSCALL)
				m->lastintr = ctl->irq;
		}else
			if(m->externup)
				m->externup->nqtrap++;

		if(ctl->isr)
			ctl->isr(vno);
		for(v = ctl; v != nil; v = v->next){
			if(v->f)
				v->f(ureg, v->a);
		}
		if(ctl->eoi)
			ctl->eoi(vno);
		intrtime(vno);
		if(ctl->isintr){
			if(ctl->irq == IrqCLOCK || ctl->irq == IrqTIMER)
				clockintr = 1;

			if(m->externup && !clockintr)
				preempted();
		}
	}
	else if(vno < nelem(excname) && user){
		spllo();
		snprint(buf, sizeof buf, "sys: trap: %s", excname[vno]);
		postnote(m->externup, 1, buf, NDebug);
	}
	else if(vno >= VectorPIC && vno != VectorSYSCALL){
		/*
		 * An unknown interrupt.
		 * Check for a default IRQ7. This can happen when
		 * the IRQ input goes away before the acknowledge.
		 * In this case, a 'default IRQ7' is generated, but
		 * the corresponding bit in the ISR isn't set.
		 * In fact, just ignore all such interrupts.
		 */

		/* clear the interrupt */
		i8259isr(vno);

		iprint("cpu%d: spurious interrupt %d, last %d\n",
			m->machno, vno, m->lastintr);
		intrtime(vno);
		if(user)
			kexit(ureg);
		return;
	}
	else{
		if(vno == VectorNMI){
			nmienable();
			if(m->machno != 0){
				iprint("cpu%d: PC %#llux\n",
					m->machno, ureg->ip);
				for(;;);
			}
		}
		dumpregs(ureg);
		if(!user){
			ureg->sp = PTR2UINT(&ureg->sp);
			dumpstackwithureg(ureg);
		}
		if(vno < nelem(excname))
			panic("%s", excname[vno]);
		panic("unknown trap/intr: %d\n", vno);
	}
	splhi();

	/* delaysched set because we held a lock or because our quantum ended */
	if(m->externup && m->externup->delaysched && clockintr){
		if(0)
		if(user && m->externup->ac == nil && m->externup->nqtrap == 0 && m->externup->nqsyscall == 0){
			if(!waserror()){
				m->externup->ac = getac(m->externup, -1);
				poperror();
				runacore();
				return;
			}
		}
		sched();
		splhi();
	}


	if(user){
		if(m->externup && m->externup->procctl || m->externup->nnote)
			notify(ureg);
		kexit(ureg);
	}
}
Exemple #30
0
//This is run in interrupt context and apart from initialization and destruction, this is the only code
//touching the host (=spihost[x]) variable. The rest of the data arrives in queues. That is why there are
//no muxes in this code.
static void IRAM_ATTR spi_intr(void *arg)
{
    BaseType_t r;
    BaseType_t do_yield = pdFALSE;
    spi_slave_transaction_t *trans = NULL;
    spi_slave_t *host = (spi_slave_t *)arg;

#ifdef DEBUG_SLAVE
    dumpregs(host->hw);
    if (host->dmadesc_rx) dumpll(&host->dmadesc_rx[0]);
#endif

    //Ignore all but the trans_done int.
    if (!host->hw->slave.trans_done) return;

    if (host->cur_trans) {
        if (host->dma_chan == 0 && host->cur_trans->rx_buffer) {
            //Copy result out
            uint32_t *data = host->cur_trans->rx_buffer;
            for (int x = 0; x < host->cur_trans->length; x += 32) {
                uint32_t word;
                int len = host->cur_trans->length - x;
                if (len > 32) len = 32;
                word = host->hw->data_buf[(x / 32)];
                memcpy(&data[x / 32], &word, (len + 7) / 8);
            }
        } else if (host->dma_chan != 0 && host->cur_trans->rx_buffer) {
            int i;
            //In case CS goes high too soon, the transfer is aborted while the DMA channel still thinks it's going. This
            //leads to issues later on, so in that case we need to reset the channel. The state can be detected because
            //the DMA system doesn't give back the offending descriptor; the owner is still set to DMA.
            for (i = 0; host->dmadesc_rx[i].eof == 0 && host->dmadesc_rx[i].owner == 0; i++) ;
            if (host->dmadesc_rx[i].owner) {
                spicommon_dmaworkaround_req_reset(host->dma_chan, spi_slave_restart_after_dmareset, host);
            }
        }
        if (host->cfg.post_trans_cb) host->cfg.post_trans_cb(host->cur_trans);
        //Okay, transaction is done.
        //Return transaction descriptor.
        xQueueSendFromISR(host->ret_queue, &host->cur_trans, &do_yield);
        host->cur_trans = NULL;
    }
    if (host->dma_chan != 0) {
        spicommon_dmaworkaround_idle(host->dma_chan);
        if (spicommon_dmaworkaround_reset_in_progress()) {
            //We need to wait for the reset to complete. Disable int (will be re-enabled on reset callback) and exit isr.
            esp_intr_disable(host->intr);
            if (do_yield) portYIELD_FROM_ISR();
            return;
        }
    }

    //Grab next transaction
    r = xQueueReceiveFromISR(host->trans_queue, &trans, &do_yield);
    if (!r) {
        //No packet waiting. Disable interrupt.
        esp_intr_disable(host->intr);
    } else {
        //We have a transaction. Send it.
        host->hw->slave.trans_done = 0; //clear int bit
        host->cur_trans = trans;

        if (host->dma_chan != 0) {
            spicommon_dmaworkaround_transfer_active(host->dma_chan);
            host->hw->dma_conf.val |= SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST;
            host->hw->dma_out_link.start = 0;
            host->hw->dma_in_link.start = 0;
            host->hw->dma_conf.val &= ~(SPI_OUT_RST | SPI_IN_RST | SPI_AHBM_RST | SPI_AHBM_FIFO_RST);
            host->hw->dma_conf.out_data_burst_en = 0;
            host->hw->dma_conf.indscr_burst_en = 0;
            host->hw->dma_conf.outdscr_burst_en = 0;

            //Fill DMA descriptors
            if (trans->rx_buffer) {
                host->hw->user.usr_miso_highpart = 0;
                spicommon_setup_dma_desc_links(host->dmadesc_rx, ((trans->length + 7) / 8), trans->rx_buffer, true);
                host->hw->dma_in_link.addr = (int)(&host->dmadesc_rx[0]) & 0xFFFFF;
                host->hw->dma_in_link.start = 1;
            }

            if (trans->tx_buffer) {
                spicommon_setup_dma_desc_links(host->dmadesc_tx, (trans->length + 7) / 8, trans->tx_buffer, false);
                host->hw->user.usr_mosi_highpart = 0;
                host->hw->dma_out_link.addr = (int)(&host->dmadesc_tx[0]) & 0xFFFFF;
                host->hw->dma_out_link.start = 1;
            }

            host->hw->slave.sync_reset = 1;
            host->hw->slave.sync_reset = 0;

        } else {
            //No DMA. Turn off SPI and copy data to transmit buffers.
            host->hw->cmd.usr = 0;
            host->hw->slave.sync_reset = 1;
            host->hw->slave.sync_reset = 0;

            host->hw->user.usr_miso_highpart = 0;
            host->hw->user.usr_mosi_highpart = 0;
            if (trans->tx_buffer) {
                const uint32_t *data = host->cur_trans->tx_buffer;
                for (int x = 0; x < trans->length; x += 32) {
                    uint32_t word;
                    memcpy(&word, &data[x / 32], 4);
                    host->hw->data_buf[(x / 32)] = word;
                }
            }
        }

        host->hw->slv_rd_bit.slv_rdata_bit = 0;
        host->hw->slv_wrbuf_dlen.bit_len = trans->length - 1;
        host->hw->slv_rdbuf_dlen.bit_len = trans->length - 1;
        host->hw->mosi_dlen.usr_mosi_dbitlen = trans->length - 1;
        host->hw->miso_dlen.usr_miso_dbitlen = trans->length - 1;
        host->hw->user.usr_mosi = (trans->tx_buffer == NULL) ? 0 : 1;
        host->hw->user.usr_miso = (trans->rx_buffer == NULL) ? 0 : 1;

        //Kick off transfer
        host->hw->cmd.usr = 1;
        if (host->cfg.post_setup_cb) host->cfg.post_setup_cb(trans);
    }
    if (do_yield) portYIELD_FROM_ISR();
}