xref: /plan9/sys/src/cmd/ki/ki.c (revision bb43afe423a7a925fe6bf0f50e9f0e6b24a63d80)
13e12c5d1SDavid du Colombier #include <u.h>
23e12c5d1SDavid du Colombier #include <libc.h>
33e12c5d1SDavid du Colombier #include <bio.h>
4bd389b36SDavid du Colombier #include <mach.h>
5*bb43afe4SDavid du Colombier #include <tos.h>
63e12c5d1SDavid du Colombier #define Extern
73e12c5d1SDavid du Colombier #include "sparc.h"
83e12c5d1SDavid du Colombier 
93e12c5d1SDavid du Colombier char	*file = "k.out";
103e12c5d1SDavid du Colombier int	datasize;
113e12c5d1SDavid du Colombier ulong	textbase;
123e12c5d1SDavid du Colombier Biobuf	bp, bi;
13219b2ee8SDavid du Colombier Fhdr	fhdr;
143e12c5d1SDavid du Colombier 
153e12c5d1SDavid du Colombier void
main(int argc,char ** argv)163e12c5d1SDavid du Colombier main(int argc, char **argv)
173e12c5d1SDavid du Colombier {
183e12c5d1SDavid du Colombier 	int pid;
193e12c5d1SDavid du Colombier 
203e12c5d1SDavid du Colombier 	argc--;
213e12c5d1SDavid du Colombier 	argv++;
223e12c5d1SDavid du Colombier 
233e12c5d1SDavid du Colombier 	bioout = &bp;
243e12c5d1SDavid du Colombier 	bin = &bi;
253e12c5d1SDavid du Colombier 	Binit(bioout, 1, OWRITE);
263e12c5d1SDavid du Colombier 	Binit(bin, 0, OREAD);
273e12c5d1SDavid du Colombier 
283e12c5d1SDavid du Colombier 	if(argc) {
293e12c5d1SDavid du Colombier 		pid = atoi(argv[0]);
303e12c5d1SDavid du Colombier 		if(pid != 0) {
313e12c5d1SDavid du Colombier 			procinit(pid);
323e12c5d1SDavid du Colombier 			cmd();
333e12c5d1SDavid du Colombier 		}
343e12c5d1SDavid du Colombier 		file = argv[0];
353e12c5d1SDavid du Colombier 	}
363e12c5d1SDavid du Colombier 	argc--;
373e12c5d1SDavid du Colombier 	argv++;
383e12c5d1SDavid du Colombier 
393e12c5d1SDavid du Colombier 	text = open(file, OREAD);
403e12c5d1SDavid du Colombier 	if(text < 0)
413e12c5d1SDavid du Colombier 		fatal(1, "open text '%s'", file);
423e12c5d1SDavid du Colombier 
433e12c5d1SDavid du Colombier 	Bprint(bioout, "ki\n");
44219b2ee8SDavid du Colombier 	inithdr(text);
45219b2ee8SDavid du Colombier 	initstk(argc, argv);
463e12c5d1SDavid du Colombier 
473e12c5d1SDavid du Colombier 	reg.fd[13] = 0.5;	/* Normally initialised by the kernel */
483e12c5d1SDavid du Colombier 	reg.fd[12] = 0.0;
493e12c5d1SDavid du Colombier 	reg.fd[14] = 1.0;
503e12c5d1SDavid du Colombier 	reg.fd[15] = 2.0;
513e12c5d1SDavid du Colombier 	cmd();
523e12c5d1SDavid du Colombier }
533e12c5d1SDavid du Colombier 
543e12c5d1SDavid du Colombier void
initmap(void)55219b2ee8SDavid du Colombier initmap(void)
563e12c5d1SDavid du Colombier {
57219b2ee8SDavid du Colombier 
58219b2ee8SDavid du Colombier 	ulong t, d, b, bssend;
59219b2ee8SDavid du Colombier 	Segment *s;
60219b2ee8SDavid du Colombier 
61219b2ee8SDavid du Colombier 	t = (fhdr.txtaddr+fhdr.txtsz+(BY2PG-1)) & ~(BY2PG-1);
62219b2ee8SDavid du Colombier 	d = (t + fhdr.datsz + (BY2PG-1)) & ~(BY2PG-1);
63219b2ee8SDavid du Colombier 	bssend = t + fhdr.datsz + fhdr.bsssz;
64219b2ee8SDavid du Colombier 	b = (bssend + (BY2PG-1)) & ~(BY2PG-1);
65219b2ee8SDavid du Colombier 
66219b2ee8SDavid du Colombier 	s = &memory.seg[Text];
67219b2ee8SDavid du Colombier 	s->type = Text;
68219b2ee8SDavid du Colombier 	s->base = fhdr.txtaddr - fhdr.hdrsz;
69219b2ee8SDavid du Colombier 	s->end = t;
70219b2ee8SDavid du Colombier 	s->fileoff = fhdr.txtoff - fhdr.hdrsz;
71219b2ee8SDavid du Colombier 	s->fileend = s->fileoff + fhdr.txtsz;
720ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
73219b2ee8SDavid du Colombier 
74219b2ee8SDavid du Colombier 	iprof = emalloc(((s->end-s->base)/PROFGRAN)*sizeof(long));
75219b2ee8SDavid du Colombier 	textbase = s->base;
76219b2ee8SDavid du Colombier 
77219b2ee8SDavid du Colombier 	s = &memory.seg[Data];
78219b2ee8SDavid du Colombier 	s->type = Data;
79219b2ee8SDavid du Colombier 	s->base = t;
80219b2ee8SDavid du Colombier 	s->end = t+(d-t);
81219b2ee8SDavid du Colombier 	s->fileoff = fhdr.datoff;
82219b2ee8SDavid du Colombier 	s->fileend = s->fileoff + fhdr.datsz;
83219b2ee8SDavid du Colombier 	datasize = fhdr.datsz;
840ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
85219b2ee8SDavid du Colombier 
86219b2ee8SDavid du Colombier 	s = &memory.seg[Bss];
87219b2ee8SDavid du Colombier 	s->type = Bss;
88219b2ee8SDavid du Colombier 	s->base = d;
89219b2ee8SDavid du Colombier 	s->end = d+(b-d);
900ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
91219b2ee8SDavid du Colombier 
92219b2ee8SDavid du Colombier 	s = &memory.seg[Stack];
93219b2ee8SDavid du Colombier 	s->type = Stack;
94219b2ee8SDavid du Colombier 	s->base = STACKTOP-STACKSIZE;
95219b2ee8SDavid du Colombier 	s->end = STACKTOP;
960ce5db6cSDavid du Colombier 	s->table = emalloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
97219b2ee8SDavid du Colombier 
98219b2ee8SDavid du Colombier 	reg.pc = fhdr.entry;
99219b2ee8SDavid du Colombier }
100219b2ee8SDavid du Colombier 
101219b2ee8SDavid du Colombier void
inithdr(int fd)102219b2ee8SDavid du Colombier inithdr(int fd)
103219b2ee8SDavid du Colombier {
104219b2ee8SDavid du Colombier 	Symbol s;
105219b2ee8SDavid du Colombier 
106219b2ee8SDavid du Colombier 	extern Machdata sparcmach;
107219b2ee8SDavid du Colombier 
1083e12c5d1SDavid du Colombier 	seek(fd, 0, 0);
109219b2ee8SDavid du Colombier 	if (!crackhdr(fd, &fhdr))
1103e12c5d1SDavid du Colombier 		fatal(0, "read text header");
1113e12c5d1SDavid du Colombier 
112219b2ee8SDavid du Colombier 	if(fhdr.type != FSPARC)
1133e12c5d1SDavid du Colombier 		fatal(0, "bad magic number");
1143e12c5d1SDavid du Colombier 
115219b2ee8SDavid du Colombier 	if(syminit(fd, &fhdr) < 0)
116219b2ee8SDavid du Colombier 		fatal(0, "%r\n");
117219b2ee8SDavid du Colombier 	symmap = loadmap(symmap, fd, &fhdr);
118219b2ee8SDavid du Colombier 	if (mach->sbreg && lookup(0, mach->sbreg, &s))
119219b2ee8SDavid du Colombier 		mach->sb = s.value;
120219b2ee8SDavid du Colombier 	machdata = &sparcmach;
121219b2ee8SDavid du Colombier 	asstype = ASUNSPARC;
1223e12c5d1SDavid du Colombier }
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier ulong
greg(int f,ulong off)1253e12c5d1SDavid du Colombier greg(int f, ulong off)
1263e12c5d1SDavid du Colombier {
1273e12c5d1SDavid du Colombier 	int n;
1283e12c5d1SDavid du Colombier 	ulong l;
1293e12c5d1SDavid du Colombier 	uchar wd[BY2WD];
1303e12c5d1SDavid du Colombier 
1313e12c5d1SDavid du Colombier 	seek(f, off, 0);
1323e12c5d1SDavid du Colombier 	n = read(f, wd, BY2WD);
1333e12c5d1SDavid du Colombier 	if(n != BY2WD)
1343e12c5d1SDavid du Colombier 		fatal(1, "read register");
1353e12c5d1SDavid du Colombier 
1363e12c5d1SDavid du Colombier 	l  = wd[0]<<24;
1373e12c5d1SDavid du Colombier 	l |= wd[1]<<16;
1383e12c5d1SDavid du Colombier 	l |= wd[2]<<8;
1393e12c5d1SDavid du Colombier 	l |= wd[3];
1403e12c5d1SDavid du Colombier 	return l;
1413e12c5d1SDavid du Colombier }
1423e12c5d1SDavid du Colombier 
1433e12c5d1SDavid du Colombier ulong
1443e12c5d1SDavid du Colombier roff[] = {
1453e12c5d1SDavid du Colombier 	REGOFF(r1),	REGOFF(r2),	REGOFF(r3),
1463e12c5d1SDavid du Colombier 	REGOFF(r4),	REGOFF(r5),	REGOFF(r6),
1473e12c5d1SDavid du Colombier 	REGOFF(r7),	REGOFF(r8),	REGOFF(r9),
1483e12c5d1SDavid du Colombier 	REGOFF(r10),	REGOFF(r11),	REGOFF(r12),
1493e12c5d1SDavid du Colombier 	REGOFF(r13),	REGOFF(r14),	REGOFF(r15),
1503e12c5d1SDavid du Colombier 	REGOFF(r16),	REGOFF(r17),	REGOFF(r18),
1513e12c5d1SDavid du Colombier 	REGOFF(r19),	REGOFF(r20),	REGOFF(r21),
1523e12c5d1SDavid du Colombier 	REGOFF(r22),	REGOFF(r23),	REGOFF(r24),
1533e12c5d1SDavid du Colombier 	REGOFF(r25),	REGOFF(r26),	REGOFF(r27),
1543e12c5d1SDavid du Colombier 	REGOFF(r28)
1553e12c5d1SDavid du Colombier };
1563e12c5d1SDavid du Colombier 
1573e12c5d1SDavid du Colombier void
seginit(int fd,Segment * s,int idx,ulong vastart,ulong vaend)158219b2ee8SDavid du Colombier seginit(int fd, Segment *s, int idx, ulong vastart, ulong vaend)
159219b2ee8SDavid du Colombier {
160219b2ee8SDavid du Colombier 	int n;
161219b2ee8SDavid du Colombier 
162219b2ee8SDavid du Colombier 	while(vastart < vaend) {
163219b2ee8SDavid du Colombier 		seek(fd, vastart, 0);
164219b2ee8SDavid du Colombier 		s->table[idx] = emalloc(BY2PG);
165219b2ee8SDavid du Colombier 		n = read(fd, s->table[idx], BY2PG);
166219b2ee8SDavid du Colombier 		if(n != BY2PG)
167219b2ee8SDavid du Colombier 			fatal(1, "data read");
168219b2ee8SDavid du Colombier 		vastart += BY2PG;
169219b2ee8SDavid du Colombier 		idx++;
170219b2ee8SDavid du Colombier 	}
171219b2ee8SDavid du Colombier }
172219b2ee8SDavid du Colombier 
173219b2ee8SDavid du Colombier void
procinit(int pid)1743e12c5d1SDavid du Colombier procinit(int pid)
1753e12c5d1SDavid du Colombier {
1763e12c5d1SDavid du Colombier 	char *p;
1773e12c5d1SDavid du Colombier 	Segment *s;
1783e12c5d1SDavid du Colombier 	int n, m, sg, i;
179219b2ee8SDavid du Colombier 	ulong vastart, vaend;
1803e12c5d1SDavid du Colombier 	char mfile[128], tfile[128], sfile[1024];
1813e12c5d1SDavid du Colombier 
1823e12c5d1SDavid du Colombier 	sprint(mfile, "/proc/%d/mem", pid);
1833e12c5d1SDavid du Colombier 	sprint(tfile, "/proc/%d/text", pid);
1843e12c5d1SDavid du Colombier 	sprint(sfile, "/proc/%d/segment", pid);
1853e12c5d1SDavid du Colombier 
1863e12c5d1SDavid du Colombier 	text = open(tfile, OREAD);
1873e12c5d1SDavid du Colombier 	if(text < 0)
1883e12c5d1SDavid du Colombier 		fatal(1, "open text %s", tfile);
189219b2ee8SDavid du Colombier 	inithdr(text);
1903e12c5d1SDavid du Colombier 
1913e12c5d1SDavid du Colombier 	sg = open(sfile, OREAD);
1923e12c5d1SDavid du Colombier 	if(sg < 0)
1933e12c5d1SDavid du Colombier 		fatal(1, "open text %s", sfile);
1943e12c5d1SDavid du Colombier 
1953e12c5d1SDavid du Colombier 	n = read(sg, sfile, sizeof(sfile));
1963e12c5d1SDavid du Colombier 	if(n >= sizeof(sfile))
1973e12c5d1SDavid du Colombier 		fatal(0, "segment file buffer too small");
1983e12c5d1SDavid du Colombier 	close(sg);
1993e12c5d1SDavid du Colombier 
2003e12c5d1SDavid du Colombier 	m = open(mfile, OREAD);
2013e12c5d1SDavid du Colombier 	if(m < 0)
2023e12c5d1SDavid du Colombier 		fatal(1, "open %s", mfile);
2033e12c5d1SDavid du Colombier 
204219b2ee8SDavid du Colombier 	initmap();
2053e12c5d1SDavid du Colombier 
2063e12c5d1SDavid du Colombier 	p = strstr(sfile, "Data");
2073e12c5d1SDavid du Colombier 	if(p == 0)
2083e12c5d1SDavid du Colombier 		fatal(0, "no data");
2093e12c5d1SDavid du Colombier 
2103e12c5d1SDavid du Colombier 	vastart = strtoul(p+9, 0, 16);
2113e12c5d1SDavid du Colombier 	vaend = strtoul(p+18, 0, 16);
2123e12c5d1SDavid du Colombier 	s = &memory.seg[Data];
213219b2ee8SDavid du Colombier 	if(s->base != vastart || s->end != vaend) {
2143e12c5d1SDavid du Colombier 		s->base = vastart;
2153e12c5d1SDavid du Colombier 		s->end = vaend;
216219b2ee8SDavid du Colombier 		free(s->table);
2170ce5db6cSDavid du Colombier 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
2183e12c5d1SDavid du Colombier 	}
219219b2ee8SDavid du Colombier 	seginit(m, s, 0, vastart, vaend);
2203e12c5d1SDavid du Colombier 
2213e12c5d1SDavid du Colombier 	p = strstr(sfile, "Bss");
2223e12c5d1SDavid du Colombier 	if(p == 0)
2233e12c5d1SDavid du Colombier 		fatal(0, "no bss");
2243e12c5d1SDavid du Colombier 
2253e12c5d1SDavid du Colombier 	vastart = strtoul(p+9, 0, 16);
2263e12c5d1SDavid du Colombier 	vaend = strtoul(p+18, 0, 16);
2273e12c5d1SDavid du Colombier 	s = &memory.seg[Bss];
228219b2ee8SDavid du Colombier 	if(s->base != vastart || s->end != vaend) {
2293e12c5d1SDavid du Colombier 		s->base = vastart;
2303e12c5d1SDavid du Colombier 		s->end = vaend;
231219b2ee8SDavid du Colombier 		free(s->table);
2320ce5db6cSDavid du Colombier 		s->table = malloc(((s->end-s->base)/BY2PG)*sizeof(uchar*));
2333e12c5d1SDavid du Colombier 	}
234219b2ee8SDavid du Colombier 	seginit(m, s, 0, vastart, vaend);
2353e12c5d1SDavid du Colombier 
2363e12c5d1SDavid du Colombier 	reg.pc = greg(m, REGOFF(pc));
2373e12c5d1SDavid du Colombier 	reg.r[1] = greg(m, REGOFF(sp));
2383e12c5d1SDavid du Colombier 	reg.r[30] = greg(m, REGOFF(r30));
2393e12c5d1SDavid du Colombier 	reg.r[31] = greg(m, REGOFF(r31));
2403e12c5d1SDavid du Colombier 
2413e12c5d1SDavid du Colombier 	for(i = 1; i < 29; i++)
2423e12c5d1SDavid du Colombier 		reg.r[i] = greg(m, roff[i-1]);
2433e12c5d1SDavid du Colombier 
2443e12c5d1SDavid du Colombier 	s = &memory.seg[Stack];
2453e12c5d1SDavid du Colombier 	vastart = reg.r[1] & ~(BY2PG-1);
246219b2ee8SDavid du Colombier 	seginit(m, s, (vastart-s->base)/BY2PG, vastart, STACKTOP);
2473e12c5d1SDavid du Colombier 	close(m);
2483e12c5d1SDavid du Colombier 	Bprint(bioout, "ki\n");
2493e12c5d1SDavid du Colombier }
2503e12c5d1SDavid du Colombier 
2513e12c5d1SDavid du Colombier void
reset(void)2523e12c5d1SDavid du Colombier reset(void)
2533e12c5d1SDavid du Colombier {
2543e12c5d1SDavid du Colombier 	int i, l, m;
2553e12c5d1SDavid du Colombier 	Segment *s;
2563e12c5d1SDavid du Colombier 	Breakpoint *b;
2573e12c5d1SDavid du Colombier 
2583e12c5d1SDavid du Colombier 	memset(&reg, 0, sizeof(Registers));
2593e12c5d1SDavid du Colombier 	reg.fd[13] = 0.5;	/* Normally initialised by the kernel */
2603e12c5d1SDavid du Colombier 	reg.fd[12] = 0.0;
2613e12c5d1SDavid du Colombier 	reg.fd[14] = 1.0;
2623e12c5d1SDavid du Colombier 	reg.fd[15] = 2.0;
2633e12c5d1SDavid du Colombier 	for(i = 0; i > Nseg; i++) {
2643e12c5d1SDavid du Colombier 		s = &memory.seg[i];
2650ce5db6cSDavid du Colombier 		l = ((s->end-s->base)/BY2PG)*sizeof(uchar*);
2663e12c5d1SDavid du Colombier 		for(m = 0; m < l; m++)
2673e12c5d1SDavid du Colombier 			if(s->table[m])
2683e12c5d1SDavid du Colombier 				free(s->table[m]);
2693e12c5d1SDavid du Colombier 		free(s->table);
2703e12c5d1SDavid du Colombier 	}
271219b2ee8SDavid du Colombier 	free(iprof);
2723e12c5d1SDavid du Colombier 	memset(&memory, 0, sizeof(memory));
2733e12c5d1SDavid du Colombier 
2743e12c5d1SDavid du Colombier 	for(b = bplist; b; b = b->next)
2753e12c5d1SDavid du Colombier 		b->done = b->count;
2763e12c5d1SDavid du Colombier }
2773e12c5d1SDavid du Colombier 
2783e12c5d1SDavid du Colombier void
initstk(int argc,char * argv[])279219b2ee8SDavid du Colombier initstk(int argc, char *argv[])
2803e12c5d1SDavid du Colombier {
281*bb43afe4SDavid du Colombier 	ulong size, sp, ap, tos;
2823e12c5d1SDavid du Colombier 	int i;
2833e12c5d1SDavid du Colombier 	char *p;
2843e12c5d1SDavid du Colombier 
285219b2ee8SDavid du Colombier 	initmap();
286*bb43afe4SDavid du Colombier 	tos = STACKTOP - sizeof(Tos)*2;	/* we'll assume twice the host's is big enough */
287*bb43afe4SDavid du Colombier 	sp = tos;
288*bb43afe4SDavid du Colombier 	for (i = 0; i < sizeof(Tos)*2; i++)
289*bb43afe4SDavid du Colombier 		putmem_b(tos + i, 0);
290*bb43afe4SDavid du Colombier 
291*bb43afe4SDavid du Colombier 	/*
292*bb43afe4SDavid du Colombier 	 * pid is second word from end of tos and needs to be set for nsec().
293*bb43afe4SDavid du Colombier 	 * we know sparc is a 32-bit cpu, so we'll assume knowledge of the Tos
294*bb43afe4SDavid du Colombier 	 * struct for now, and use our pid.
295*bb43afe4SDavid du Colombier 	 */
296*bb43afe4SDavid du Colombier 	putmem_w(tos + 4*4 + 2*sizeof(ulong) + 3*sizeof(uvlong), getpid());
2973e12c5d1SDavid du Colombier 
2983e12c5d1SDavid du Colombier 	/* Build exec stack */
299bd389b36SDavid du Colombier 	size = strlen(file)+1+BY2WD+BY2WD+(BY2WD*2);
3003e12c5d1SDavid du Colombier 	for(i = 0; i < argc; i++)
3013e12c5d1SDavid du Colombier 		size += strlen(argv[i])+BY2WD+1;
3023e12c5d1SDavid du Colombier 
3033e12c5d1SDavid du Colombier 	sp -= size;
304bd389b36SDavid du Colombier 	sp &= ~7;
3053e12c5d1SDavid du Colombier 	reg.r[1] = sp;
306*bb43afe4SDavid du Colombier 	reg.r[7] = tos;		/* Plan 9 profiling clock, etc. */
3073e12c5d1SDavid du Colombier 
3083e12c5d1SDavid du Colombier 	/* Push argc */
3093e12c5d1SDavid du Colombier 	putmem_w(sp, argc+1);
3103e12c5d1SDavid du Colombier 	sp += BY2WD;
3113e12c5d1SDavid du Colombier 
3123e12c5d1SDavid du Colombier 	/* Compute sizeof(argv) and push argv[0] */
3133e12c5d1SDavid du Colombier 	ap = sp+((argc+1)*BY2WD)+BY2WD;
3143e12c5d1SDavid du Colombier 	putmem_w(sp, ap);
3153e12c5d1SDavid du Colombier 	sp += BY2WD;
3163e12c5d1SDavid du Colombier 
3173e12c5d1SDavid du Colombier 	/* Build argv[0] string into stack */
3183e12c5d1SDavid du Colombier 	for(p = file; *p; p++)
3193e12c5d1SDavid du Colombier 		putmem_b(ap++, *p);
3203e12c5d1SDavid du Colombier 
3213e12c5d1SDavid du Colombier 	putmem_b(ap++, '\0');
3223e12c5d1SDavid du Colombier 
3233e12c5d1SDavid du Colombier 	/* Loop through pushing the arguments */
3243e12c5d1SDavid du Colombier 	for(i = 0; i < argc; i++) {
3253e12c5d1SDavid du Colombier 		putmem_w(sp, ap);
3263e12c5d1SDavid du Colombier 		sp += BY2WD;
3273e12c5d1SDavid du Colombier 		for(p = argv[i]; *p; p++)
3283e12c5d1SDavid du Colombier 			putmem_b(ap++, *p);
3293e12c5d1SDavid du Colombier 		putmem_b(ap++, '\0');
3303e12c5d1SDavid du Colombier 	}
3313e12c5d1SDavid du Colombier 	/* Null terminate argv */
3323e12c5d1SDavid du Colombier 	putmem_w(sp, 0);
3333e12c5d1SDavid du Colombier 
3343e12c5d1SDavid du Colombier }
3353e12c5d1SDavid du Colombier 
3363e12c5d1SDavid du Colombier void
fatal(int syserr,char * fmt,...)3373e12c5d1SDavid du Colombier fatal(int syserr, char *fmt, ...)
3383e12c5d1SDavid du Colombier {
3399a747e4fSDavid du Colombier 	char buf[ERRMAX], *s;
3407dd7cddfSDavid du Colombier 	va_list arg;
3413e12c5d1SDavid du Colombier 
3427dd7cddfSDavid du Colombier 	va_start(arg, fmt);
3439a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
3447dd7cddfSDavid du Colombier 	va_end(arg);
3453e12c5d1SDavid du Colombier 	s = "ki: %s\n";
3463e12c5d1SDavid du Colombier 	if(syserr)
3473e12c5d1SDavid du Colombier 		s = "ki: %s: %r\n";
3483e12c5d1SDavid du Colombier 	fprint(2, s, buf);
3493e12c5d1SDavid du Colombier 	exits(buf);
3503e12c5d1SDavid du Colombier }
3513e12c5d1SDavid du Colombier 
3523e12c5d1SDavid du Colombier void
itrace(char * fmt,...)3533e12c5d1SDavid du Colombier itrace(char *fmt, ...)
3543e12c5d1SDavid du Colombier {
3553e12c5d1SDavid du Colombier 	char buf[128];
3567dd7cddfSDavid du Colombier 	va_list arg;
3573e12c5d1SDavid du Colombier 
3587dd7cddfSDavid du Colombier 	va_start(arg, fmt);
3599a747e4fSDavid du Colombier 	vseprint(buf, buf+sizeof(buf), fmt, arg);
3607dd7cddfSDavid du Colombier 	va_end(arg);
3613e12c5d1SDavid du Colombier 	Bprint(bioout, "%8lux %.8lux %s\n", reg.pc, reg.ir, buf);
3623e12c5d1SDavid du Colombier }
3633e12c5d1SDavid du Colombier 
3643e12c5d1SDavid du Colombier void
dumpreg(void)3653e12c5d1SDavid du Colombier dumpreg(void)
3663e12c5d1SDavid du Colombier {
3673e12c5d1SDavid du Colombier 	int i;
3683e12c5d1SDavid du Colombier 
3693e12c5d1SDavid du Colombier 	Bprint(bioout, "PC  #%-8lux SP  #%-8lux Y   #%-8lux PSR #%-8lux\n",
3703e12c5d1SDavid du Colombier 				reg.pc, reg.r[1], reg.Y, reg.psr);
3713e12c5d1SDavid du Colombier 
3723e12c5d1SDavid du Colombier 	for(i = 0; i < 32; i++) {
3733e12c5d1SDavid du Colombier 		if((i%4) == 0 && i != 0)
3743e12c5d1SDavid du Colombier 			Bprint(bioout, "\n");
3753e12c5d1SDavid du Colombier 		Bprint(bioout, "R%-2d #%-8lux ", i, reg.r[i]);
3763e12c5d1SDavid du Colombier 	}
3773e12c5d1SDavid du Colombier 	Bprint(bioout, "\n");
3783e12c5d1SDavid du Colombier }
3793e12c5d1SDavid du Colombier 
3803e12c5d1SDavid du Colombier void
dumpfreg(void)3813e12c5d1SDavid du Colombier dumpfreg(void)
3823e12c5d1SDavid du Colombier {
3833e12c5d1SDavid du Colombier 	int i;
384219b2ee8SDavid du Colombier 	char buf[64];
3853e12c5d1SDavid du Colombier 
3863e12c5d1SDavid du Colombier 	i = 0;
3873e12c5d1SDavid du Colombier 	while(i < 32) {
388219b2ee8SDavid du Colombier 		ieeesftos(buf, sizeof(buf), reg.di[i]);
389219b2ee8SDavid du Colombier 		Bprint(bioout, "F%-2d %s\t", i, buf);
3903e12c5d1SDavid du Colombier 		i++;
391219b2ee8SDavid du Colombier 		ieeesftos(buf, sizeof(buf), reg.di[i]);
392219b2ee8SDavid du Colombier 		Bprint(bioout, "\tF%-2d %s\n", i, buf);
3933e12c5d1SDavid du Colombier 		i++;
3943e12c5d1SDavid du Colombier 	}
3953e12c5d1SDavid du Colombier }
3963e12c5d1SDavid du Colombier 
3973e12c5d1SDavid du Colombier void
dumpdreg(void)3983e12c5d1SDavid du Colombier dumpdreg(void)
3993e12c5d1SDavid du Colombier {
4003e12c5d1SDavid du Colombier 	int i;
401219b2ee8SDavid du Colombier 	char buf[64];
4023e12c5d1SDavid du Colombier 
4033e12c5d1SDavid du Colombier 	i = 0;
4043e12c5d1SDavid du Colombier 	while(i < 32) {
405219b2ee8SDavid du Colombier 		ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);
406219b2ee8SDavid du Colombier 		Bprint(bioout, "F%-2d %s\t", i, buf);
4073e12c5d1SDavid du Colombier 		i += 2;
408219b2ee8SDavid du Colombier 		ieeedftos(buf, sizeof(buf), reg.di[i] ,reg.di[i+1]);
409219b2ee8SDavid du Colombier 		Bprint(bioout, "\tF%-2d %s\n", i, buf);
4103e12c5d1SDavid du Colombier 		i += 2;
4113e12c5d1SDavid du Colombier 	}
4123e12c5d1SDavid du Colombier }
4133e12c5d1SDavid du Colombier 
4143e12c5d1SDavid du Colombier void *
emalloc(ulong size)4153e12c5d1SDavid du Colombier emalloc(ulong size)
4163e12c5d1SDavid du Colombier {
4173e12c5d1SDavid du Colombier 	void *a;
4183e12c5d1SDavid du Colombier 
4193e12c5d1SDavid du Colombier 	a = malloc(size);
4203e12c5d1SDavid du Colombier 	if(a == 0)
4213e12c5d1SDavid du Colombier 		fatal(0, "no memory");
4223e12c5d1SDavid du Colombier 
4233e12c5d1SDavid du Colombier 	memset(a, 0, size);
4243e12c5d1SDavid du Colombier 	return a;
4253e12c5d1SDavid du Colombier }
4263e12c5d1SDavid du Colombier 
4273e12c5d1SDavid du Colombier void *
erealloc(void * a,ulong oldsize,ulong size)4283e12c5d1SDavid du Colombier erealloc(void *a, ulong oldsize, ulong size)
4293e12c5d1SDavid du Colombier {
4303e12c5d1SDavid du Colombier 	void *n;
4313e12c5d1SDavid du Colombier 
4323e12c5d1SDavid du Colombier 	n = malloc(size);
4333e12c5d1SDavid du Colombier 	if(n == 0)
4343e12c5d1SDavid du Colombier 		fatal(0, "no memory");
4353e12c5d1SDavid du Colombier 	memset(n, 0, size);
4363e12c5d1SDavid du Colombier 	if(size > oldsize)
4373e12c5d1SDavid du Colombier 		size = oldsize;
4383e12c5d1SDavid du Colombier 	memmove(n, a, size);
4393e12c5d1SDavid du Colombier 	return n;
4403e12c5d1SDavid du Colombier }
4413e12c5d1SDavid du Colombier 
4423e12c5d1SDavid du Colombier Mulu
mulu(ulong u1,ulong u2)4433e12c5d1SDavid du Colombier mulu(ulong u1, ulong u2)
4443e12c5d1SDavid du Colombier {
4453e12c5d1SDavid du Colombier 	ulong lo1, lo2, hi1, hi2, lo, hi, t1, t2, t;
4463e12c5d1SDavid du Colombier 
4473e12c5d1SDavid du Colombier 	lo1 = u1 & 0xffff;
4483e12c5d1SDavid du Colombier 	lo2 = u2 & 0xffff;
4493e12c5d1SDavid du Colombier 	hi1 = u1 >> 16;
4503e12c5d1SDavid du Colombier 	hi2 = u2 >> 16;
4513e12c5d1SDavid du Colombier 
4523e12c5d1SDavid du Colombier 	lo = lo1 * lo2;
4533e12c5d1SDavid du Colombier 	t1 = lo1 * hi2;
4543e12c5d1SDavid du Colombier 	t2 = lo2 * hi1;
4553e12c5d1SDavid du Colombier 	hi = hi1 * hi2;
4563e12c5d1SDavid du Colombier 	t = lo;
4573e12c5d1SDavid du Colombier 	lo += t1 << 16;
4583e12c5d1SDavid du Colombier 	if(lo < t)
4593e12c5d1SDavid du Colombier 		hi++;
4603e12c5d1SDavid du Colombier 	t = lo;
4613e12c5d1SDavid du Colombier 	lo += t2 << 16;
4623e12c5d1SDavid du Colombier 	if(lo < t)
4633e12c5d1SDavid du Colombier 		hi++;
4643e12c5d1SDavid du Colombier 	hi += (t1 >> 16) + (t2 >> 16);
4653e12c5d1SDavid du Colombier 	return (Mulu){lo, hi};
4663e12c5d1SDavid du Colombier }
4673e12c5d1SDavid du Colombier 
4683e12c5d1SDavid du Colombier Mul
mul(long l1,long l2)4693e12c5d1SDavid du Colombier mul(long l1, long l2)
4703e12c5d1SDavid du Colombier {
4713e12c5d1SDavid du Colombier 	Mulu m;
4723e12c5d1SDavid du Colombier 	ulong t, lo, hi;
4733e12c5d1SDavid du Colombier 	int sign;
4743e12c5d1SDavid du Colombier 
4753e12c5d1SDavid du Colombier 	sign = 0;
4763e12c5d1SDavid du Colombier 	if(l1 < 0){
4773e12c5d1SDavid du Colombier 		sign ^= 1;
4783e12c5d1SDavid du Colombier 		l1 = -l1;
4793e12c5d1SDavid du Colombier 	}
4803e12c5d1SDavid du Colombier 	if(l2 < 0){
4813e12c5d1SDavid du Colombier 		sign ^= 1;
4823e12c5d1SDavid du Colombier 		l2 = -l2;
4833e12c5d1SDavid du Colombier 	}
4843e12c5d1SDavid du Colombier 	m = mulu(l1, l2);
4853e12c5d1SDavid du Colombier 	lo = m.lo;
4863e12c5d1SDavid du Colombier 	hi = m.hi;
4873e12c5d1SDavid du Colombier 	if(sign){
4883e12c5d1SDavid du Colombier 		t = lo = ~lo;
4893e12c5d1SDavid du Colombier 		hi = ~hi;
4903e12c5d1SDavid du Colombier 		lo++;
4913e12c5d1SDavid du Colombier 		if(lo < t)
4923e12c5d1SDavid du Colombier 			hi++;
4933e12c5d1SDavid du Colombier 	}
4943e12c5d1SDavid du Colombier 	return (Mul){lo, hi};
4953e12c5d1SDavid du Colombier }
496