xref: /inferno-os/utils/libmach/t.c (revision d67b7dad77bb8aa973dad1f7c3ab0c309b114278)
174a4d8c2SCharles.Forsyth /*
274a4d8c2SCharles.Forsyth  * thumb definition
374a4d8c2SCharles.Forsyth  */
474a4d8c2SCharles.Forsyth #include <lib9.h>
574a4d8c2SCharles.Forsyth #include <bio.h>
674a4d8c2SCharles.Forsyth #include "uregt.h"
774a4d8c2SCharles.Forsyth #include "mach.h"
874a4d8c2SCharles.Forsyth 
974a4d8c2SCharles.Forsyth 
1074a4d8c2SCharles.Forsyth #define	REGOFF(x)	(ulong) (&((struct Ureg *) 0)->x)
1174a4d8c2SCharles.Forsyth 
1274a4d8c2SCharles.Forsyth #define SP		REGOFF(r13)
1374a4d8c2SCharles.Forsyth #define PC		REGOFF(pc)
1474a4d8c2SCharles.Forsyth 
1574a4d8c2SCharles.Forsyth #define	REGSIZE		sizeof(struct Ureg)
1674a4d8c2SCharles.Forsyth 
1774a4d8c2SCharles.Forsyth Reglist thumbreglist[] =
1874a4d8c2SCharles.Forsyth {
1974a4d8c2SCharles.Forsyth 	{"LINK",	REGOFF(link),		RINT|RRDONLY, 'X'},
2074a4d8c2SCharles.Forsyth 	{"TYPE",	REGOFF(type),		RINT|RRDONLY, 'X'},
2174a4d8c2SCharles.Forsyth 	{"PSR",		REGOFF(psr),		RINT|RRDONLY, 'X'},
2274a4d8c2SCharles.Forsyth 	{"PC",		PC,			RINT, 'X'},
2374a4d8c2SCharles.Forsyth 	{"SP",		SP,			RINT, 'X'},
2474a4d8c2SCharles.Forsyth 	{"R15",		PC,			RINT, 'X'},
2574a4d8c2SCharles.Forsyth 	{"R14",		REGOFF(r14),		RINT, 'X'},
2674a4d8c2SCharles.Forsyth 	{"R13",		REGOFF(r13),		RINT, 'X'},
2774a4d8c2SCharles.Forsyth 	{"R12",		REGOFF(r12),		RINT, 'X'},
2874a4d8c2SCharles.Forsyth 	{"R11",		REGOFF(r11),		RINT, 'X'},
2974a4d8c2SCharles.Forsyth 	{"R10",		REGOFF(r10),		RINT, 'X'},
3074a4d8c2SCharles.Forsyth 	{"R9",		REGOFF(r9),		RINT, 'X'},
3174a4d8c2SCharles.Forsyth 	{"R8",		REGOFF(r8),		RINT, 'X'},
3274a4d8c2SCharles.Forsyth 	{"R7",		REGOFF(r7),		RINT, 'X'},
3374a4d8c2SCharles.Forsyth 	{"R6",		REGOFF(r6),		RINT, 'X'},
3474a4d8c2SCharles.Forsyth 	{"R5",		REGOFF(r5),		RINT, 'X'},
3574a4d8c2SCharles.Forsyth 	{"R4",		REGOFF(r4),		RINT, 'X'},
3674a4d8c2SCharles.Forsyth 	{"R3",		REGOFF(r3),		RINT, 'X'},
3774a4d8c2SCharles.Forsyth 	{"R2",		REGOFF(r2),		RINT, 'X'},
3874a4d8c2SCharles.Forsyth 	{"R1",		REGOFF(r1),		RINT, 'X'},
3974a4d8c2SCharles.Forsyth 	{"R0",		REGOFF(r0),		RINT, 'X'},
4074a4d8c2SCharles.Forsyth 	{  0 }
4174a4d8c2SCharles.Forsyth };
4274a4d8c2SCharles.Forsyth 
4374a4d8c2SCharles.Forsyth 	/* the machine description */
4474a4d8c2SCharles.Forsyth Mach mthumb =
4574a4d8c2SCharles.Forsyth {
4674a4d8c2SCharles.Forsyth 	"thumb",
4774a4d8c2SCharles.Forsyth 	MARM,	/*MTHUMB,*/		/* machine type */
4874a4d8c2SCharles.Forsyth 	thumbreglist,	/* register set */
4974a4d8c2SCharles.Forsyth 	REGSIZE,	/* register set size */
5074a4d8c2SCharles.Forsyth 	0,		/* fp register set size */
5174a4d8c2SCharles.Forsyth 	"PC",		/* name of PC */
5274a4d8c2SCharles.Forsyth 	"SP",		/* name of SP */
5374a4d8c2SCharles.Forsyth 	"R15",		/* name of link register */
5474a4d8c2SCharles.Forsyth 	"setR12",	/* static base register name */
5574a4d8c2SCharles.Forsyth 	0,		/* static base register value */
5674a4d8c2SCharles.Forsyth 	0x1000,		/* page size */
5774a4d8c2SCharles.Forsyth 	0x80000000,	/* kernel base */
5874a4d8c2SCharles.Forsyth 	0,		/* kernel text mask */
59*d67b7dadSforsyth 	0x7FFFFFFF,	/* stack top */
6074a4d8c2SCharles.Forsyth 	2,		/* quantization of pc */
6174a4d8c2SCharles.Forsyth 	4,		/* szaddr */
6274a4d8c2SCharles.Forsyth 	4,		/* szreg */
6374a4d8c2SCharles.Forsyth 	4,		/* szfloat */
6474a4d8c2SCharles.Forsyth 	8,		/* szdouble */
6574a4d8c2SCharles.Forsyth };
6674a4d8c2SCharles.Forsyth 
6774a4d8c2SCharles.Forsyth typedef struct pcentry pcentry;
6874a4d8c2SCharles.Forsyth 
6974a4d8c2SCharles.Forsyth struct pcentry{
7074a4d8c2SCharles.Forsyth 	long start;
7174a4d8c2SCharles.Forsyth 	long stop;
7274a4d8c2SCharles.Forsyth };
7374a4d8c2SCharles.Forsyth 
7474a4d8c2SCharles.Forsyth static pcentry *pctab;
7574a4d8c2SCharles.Forsyth static int npctab;
7674a4d8c2SCharles.Forsyth 
7774a4d8c2SCharles.Forsyth void
thumbpctab(Biobuf * b,Fhdr * fp)7874a4d8c2SCharles.Forsyth thumbpctab(Biobuf *b, Fhdr *fp)
7974a4d8c2SCharles.Forsyth {
8074a4d8c2SCharles.Forsyth 	int n, o, ta;
8174a4d8c2SCharles.Forsyth 	uchar c[8];
8274a4d8c2SCharles.Forsyth 	pcentry *tab;
8374a4d8c2SCharles.Forsyth 
8474a4d8c2SCharles.Forsyth 	Bseek(b, fp->lnpcoff+fp->lnpcsz, 0);
8574a4d8c2SCharles.Forsyth 	o = (int)Boffset(b);
8674a4d8c2SCharles.Forsyth 	Bseek(b, 0, 2);
8774a4d8c2SCharles.Forsyth 	n = (int)Boffset(b)-o;
8874a4d8c2SCharles.Forsyth 	pctab = (pcentry*)malloc(n);
8974a4d8c2SCharles.Forsyth 	if(pctab == 0)
9074a4d8c2SCharles.Forsyth 		return;
9174a4d8c2SCharles.Forsyth 	ta = fp->txtaddr;
9274a4d8c2SCharles.Forsyth 	tab = pctab;
9374a4d8c2SCharles.Forsyth 	Bseek(b, fp->lnpcoff+fp->lnpcsz, 0);
9474a4d8c2SCharles.Forsyth 	while(Bread(b, c, sizeof(c)) == sizeof(c)){
9574a4d8c2SCharles.Forsyth 		tab->start = ta + (c[0]<<24)|(c[1]<<16)|(c[2]<<8)|c[3];
9674a4d8c2SCharles.Forsyth 		tab->stop = ta + (c[4]<<24)|(c[5]<<16)|(c[6]<<8)|c[7];
9774a4d8c2SCharles.Forsyth 		tab++;
9874a4d8c2SCharles.Forsyth 	}
9974a4d8c2SCharles.Forsyth 	npctab = n/sizeof(c);
10074a4d8c2SCharles.Forsyth }
10174a4d8c2SCharles.Forsyth 
10274a4d8c2SCharles.Forsyth int
thumbpclookup(uvlong pc)103*d67b7dadSforsyth thumbpclookup(uvlong pc)
10474a4d8c2SCharles.Forsyth {
105*d67b7dadSforsyth 	uvlong l, u, m;
10674a4d8c2SCharles.Forsyth 	pcentry *tab = pctab;
10774a4d8c2SCharles.Forsyth 
10874a4d8c2SCharles.Forsyth 	l = 0;
10974a4d8c2SCharles.Forsyth 	u = npctab-1;
11074a4d8c2SCharles.Forsyth 	while(l < u){
11174a4d8c2SCharles.Forsyth 		m = (l+u)/2;
11274a4d8c2SCharles.Forsyth 		if(pc < tab[m].start)
11374a4d8c2SCharles.Forsyth 			u = m-1;
11474a4d8c2SCharles.Forsyth 		else if(pc > tab[m].stop)
11574a4d8c2SCharles.Forsyth 			l = m+1;
11674a4d8c2SCharles.Forsyth 		else
11774a4d8c2SCharles.Forsyth 			l = u = m;
11874a4d8c2SCharles.Forsyth 	}
119*d67b7dadSforsyth 	if(l == u && u < npctab && tab[u].start <= pc && pc <= tab[u].stop)
12074a4d8c2SCharles.Forsyth 		return 1;	// thumb
12174a4d8c2SCharles.Forsyth 	return 0;	// arm
12274a4d8c2SCharles.Forsyth }
123