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