boot/zynq: add jtagload utility
This commit is contained in:
parent
d57f23fb87
commit
2d564a5004
4 changed files with 670 additions and 14 deletions
647
sys/src/boot/zynq/jtagload.c
Normal file
647
sys/src/boot/zynq/jtagload.c
Normal file
|
@ -0,0 +1,647 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
|
||||
typedef struct Tap Tap;
|
||||
typedef struct Dap Dap;
|
||||
|
||||
struct Tap
|
||||
{
|
||||
int off;
|
||||
int len;
|
||||
int delay;
|
||||
|
||||
u32int id;
|
||||
u32int dapsel;
|
||||
};
|
||||
|
||||
struct Dap
|
||||
{
|
||||
Tap *tap;
|
||||
|
||||
uint port;
|
||||
u32int id;
|
||||
};
|
||||
|
||||
int dfd = -1;
|
||||
int lastbit = -1;
|
||||
|
||||
int irlen;
|
||||
|
||||
int ntaps;
|
||||
Tap* taps;
|
||||
|
||||
int ndaps;
|
||||
Dap* daps;
|
||||
|
||||
Dap* ahbap;
|
||||
Dap* apbap;
|
||||
|
||||
/* MPSSE command bits */
|
||||
enum {
|
||||
FEW = 1<<0, /* -ve CLK on write */
|
||||
BITS = 1<<1, /* bits or bytes */
|
||||
FER = 1<<2, /* -ve CLK on read */
|
||||
LSB = 1<<3, /* LSB first = 1 else MSB first */
|
||||
TDI = 1<<4, /* do write TDI */
|
||||
TDO = 1<<5, /* do read TDO */
|
||||
TMS = 1<<6, /* do write TMS */
|
||||
};
|
||||
|
||||
void
|
||||
ioinit(char *dev)
|
||||
{
|
||||
uchar b[3];
|
||||
|
||||
dfd = open(dev, ORDWR);
|
||||
if(dfd < 0)
|
||||
sysfatal("open: %r");
|
||||
|
||||
b[0] = 0x80;
|
||||
b[1] = 0x08;
|
||||
b[2] = 0x0B;
|
||||
write(dfd, b, 3);
|
||||
}
|
||||
|
||||
void
|
||||
io(int cmd, int len, uchar *dat)
|
||||
{
|
||||
uchar buf[64];
|
||||
uchar *p = buf;
|
||||
|
||||
*p++ = cmd;
|
||||
*p++ = len-1;
|
||||
if((cmd & BITS) != 0)
|
||||
len = 1;
|
||||
else
|
||||
*p++ = (len-1)>>8;
|
||||
if((cmd & (TDI|TMS)) != 0){
|
||||
memmove(p, dat, len);
|
||||
p += len;
|
||||
}
|
||||
if(write(dfd, buf, p - buf) != (p - buf))
|
||||
sysfatal("io write: %r");
|
||||
if((cmd & TDO) != 0)
|
||||
if(readn(dfd, dat, len) != len)
|
||||
sysfatal("io read: %r");
|
||||
}
|
||||
|
||||
void
|
||||
dstate(u32int s, int len)
|
||||
{
|
||||
uchar b[1];
|
||||
|
||||
assert(len < 8);
|
||||
b[0] = s;
|
||||
if(lastbit != -1){
|
||||
b[0] |= lastbit << 7;
|
||||
lastbit = -1;
|
||||
}
|
||||
io(TMS|LSB|BITS|FEW, len, b);
|
||||
}
|
||||
uvlong
|
||||
dshift(uvlong w, int len)
|
||||
{
|
||||
uchar b[8];
|
||||
int c, s, n;
|
||||
|
||||
c = TDI|LSB|FEW;
|
||||
if(len < 0){
|
||||
len = -len;
|
||||
c |= TDO;
|
||||
}
|
||||
s = 0;
|
||||
n = len/8;
|
||||
if(n > 0) {
|
||||
switch(n){
|
||||
case 8: b[7] = w >> 56;
|
||||
case 7: b[6] = w >> 48;
|
||||
case 6: b[5] = w >> 40;
|
||||
case 5: b[4] = w >> 32;
|
||||
case 4: b[3] = w >> 24;
|
||||
case 3: b[2] = w >> 16;
|
||||
case 2: b[1] = w >> 8;
|
||||
case 1: b[0] = w >> 0;
|
||||
}
|
||||
io(c, n, b);
|
||||
s = n*8;
|
||||
if((c & TDO) != 0){
|
||||
w &= ~((1ULL<<s)-1);
|
||||
switch(n){
|
||||
case 8: w |= (uvlong)b[7] << 56;
|
||||
case 7: w |= (uvlong)b[6] << 48;
|
||||
case 6: w |= (uvlong)b[5] << 40;
|
||||
case 5: w |= (uvlong)b[4] << 32;
|
||||
case 4: w |= (uvlong)b[3] << 24;
|
||||
case 3: w |= (uvlong)b[2] << 16;
|
||||
case 2: w |= (uvlong)b[1] << 8;
|
||||
case 1: w |= (uvlong)b[0] << 0;
|
||||
}
|
||||
}
|
||||
len -= s;
|
||||
}
|
||||
if(len > 0){
|
||||
b[0] = w >> s;
|
||||
c |= BITS;
|
||||
io(c, len, b);
|
||||
if((c & TDO) != 0){
|
||||
w &= ~((uvlong)((1<<len)-1) << s);
|
||||
w |= (uvlong)(b[0] >> 8-len) << s;
|
||||
}
|
||||
s += len;
|
||||
}
|
||||
return w & (1ULL<<s)-1;
|
||||
}
|
||||
void
|
||||
dshiftones(int len)
|
||||
{
|
||||
while(len >= 64){
|
||||
dshift(~0ULL, 64);
|
||||
len -= 64;
|
||||
}
|
||||
dshift(~0ULL, len);
|
||||
}
|
||||
int
|
||||
dshiftdelay(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* send ones */
|
||||
dshiftones(512);
|
||||
for(i=0; i<512; i++){
|
||||
if(dshift(i != 0, -1) == 0)
|
||||
return i;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
irw(Tap *tap, uvlong w)
|
||||
{
|
||||
/* 0011 -> Shift-IR */
|
||||
dstate(0x3, 4);
|
||||
|
||||
dshiftones(tap->off);
|
||||
if((tap->off + tap->len) == irlen){
|
||||
dshift(w, tap->len-1);
|
||||
lastbit = w >> (tap->len-1);
|
||||
} else {
|
||||
dshift(w, tap->len);
|
||||
dshiftones(irlen - (tap->off + tap->len-1));
|
||||
lastbit = 1;
|
||||
}
|
||||
|
||||
/* 011 -> Idle */
|
||||
dstate(0x3, 3);
|
||||
}
|
||||
uvlong
|
||||
drr(Tap *tap, int len)
|
||||
{
|
||||
uvlong w, d;
|
||||
|
||||
/* 001 -> Shift-DR */
|
||||
dstate(0x1, 3);
|
||||
|
||||
d = dshift(0, -tap->delay);
|
||||
w = dshift(0, -len);
|
||||
dshift(d, tap->delay);
|
||||
dshift(w, len-1);
|
||||
lastbit = (w >> len-1) & 1;
|
||||
|
||||
/* 011 -> Idle */
|
||||
dstate(0x3, 3);
|
||||
|
||||
return w;
|
||||
}
|
||||
void
|
||||
drw(Tap *tap, uvlong w, int len)
|
||||
{
|
||||
/* 001 -> Shift-DR */
|
||||
dstate(0x1, 3);
|
||||
|
||||
dshift(0, tap->delay);
|
||||
dshift(w, len-1);
|
||||
lastbit = (w >> len-1) & 1;
|
||||
|
||||
/* 011 -> Idle */
|
||||
dstate(0x3, 3);
|
||||
}
|
||||
|
||||
enum {
|
||||
ABORT = 0x8,
|
||||
DPACC = 0xA,
|
||||
APACC = 0xB,
|
||||
CTRLSTAT = 0x4,
|
||||
SELECT = 0x8,
|
||||
RDBUF = 0xC,
|
||||
};
|
||||
|
||||
u32int
|
||||
dapr(Dap *dap, uchar r, uchar a)
|
||||
{
|
||||
uvlong w;
|
||||
|
||||
irw(dap->tap, r);
|
||||
w = 1 | (a >> 1) & 0x6;
|
||||
drw(dap->tap, w, 35);
|
||||
do {
|
||||
w = drr(dap->tap, 35);
|
||||
} while((w & 7) == 1);
|
||||
return w >> 3;
|
||||
}
|
||||
void
|
||||
dapw(Dap *dap, uchar r, uchar a, u32int v)
|
||||
{
|
||||
uvlong w;
|
||||
|
||||
irw(dap->tap, r);
|
||||
w = (a >> 1) & 0x6;
|
||||
w |= (uvlong)v << 3;
|
||||
drw(dap->tap, w, 35);
|
||||
}
|
||||
|
||||
void
|
||||
app(Dap *dap)
|
||||
{
|
||||
enum {
|
||||
CSYSPWRUPACK = 1<<31,
|
||||
CSYSPWRUPREQ = 1<<30,
|
||||
CDBGPWRUPACK = 1<<29,
|
||||
CDBGPWRUPREQ = 1<<28,
|
||||
CDBGRSTACK = 1<<27,
|
||||
CDBGRSTREQ = 1<<26,
|
||||
};
|
||||
u32int s;
|
||||
|
||||
for(;;){
|
||||
s = dapr(dap, DPACC, CTRLSTAT);
|
||||
if((s & (CDBGPWRUPACK|CSYSPWRUPACK)) == (CDBGPWRUPACK|CSYSPWRUPACK))
|
||||
break;
|
||||
s |= CSYSPWRUPREQ|CDBGPWRUPREQ;
|
||||
dapw(dap, DPACC, CTRLSTAT, s);
|
||||
}
|
||||
}
|
||||
void
|
||||
apa(Dap *dap, uchar a)
|
||||
{
|
||||
u32int s;
|
||||
|
||||
s = dap->port<<24 | a&0xf0;
|
||||
if(s != dap->tap->dapsel){
|
||||
dap->tap->dapsel = s;
|
||||
dapw(dap, DPACC, SELECT, s);
|
||||
app(dap);
|
||||
}
|
||||
}
|
||||
u32int
|
||||
apr(Dap *dap, uchar a)
|
||||
{
|
||||
apa(dap, a);
|
||||
return dapr(dap, APACC, a&0xC);
|
||||
}
|
||||
void
|
||||
apw(Dap *dap, uchar a, u32int v)
|
||||
{
|
||||
apa(dap, a);
|
||||
dapw(dap, APACC, a&0xC, v);
|
||||
}
|
||||
u32int
|
||||
mmr(Dap *ap, u32int addr)
|
||||
{
|
||||
apw(ap, 0x4, addr);
|
||||
return apr(ap, 0xC);
|
||||
}
|
||||
void
|
||||
mmw(Dap *ap, u32int addr, u32int val)
|
||||
{
|
||||
apw(ap, 0x4, addr);
|
||||
apw(ap, 0xC, val);
|
||||
}
|
||||
|
||||
void
|
||||
tapreset(void)
|
||||
{
|
||||
int i, j, o;
|
||||
|
||||
dstate(0x1F, 6); /* 011111 -> Reset->Idle */
|
||||
dstate(0x3, 4); /* 0011 -> Shift-IR */
|
||||
|
||||
irlen = dshiftdelay();
|
||||
lastbit = 1;
|
||||
|
||||
dstate(0x7, 5); /* 00111 -> Shift-IR->Shift-DR */
|
||||
|
||||
ntaps = dshiftdelay();
|
||||
|
||||
dstate(0x1F, 6); /* 011111 -> Reset->Idle */
|
||||
dstate(0x1, 3); /* 001 -> Shift-DR */
|
||||
|
||||
taps = realloc(taps, sizeof(taps[0]) * ntaps);
|
||||
|
||||
o = 0;
|
||||
for(i=ntaps-1; i>=0; i--){
|
||||
taps[i].delay = ntaps - i - 1;
|
||||
taps[i].off = o;
|
||||
taps[i].id = dshift(0, -32);
|
||||
switch(taps[i].id){
|
||||
default:
|
||||
sysfatal("unknown tapid %.8ux\n", taps[i].id);
|
||||
case 0x03727093:
|
||||
case 0x0373b093:
|
||||
case 0x23727093:
|
||||
taps[i].len = 6;
|
||||
break;
|
||||
case 0x4ba00477:
|
||||
taps[i].len = 4;
|
||||
break;
|
||||
}
|
||||
o += taps[i].len;
|
||||
}
|
||||
|
||||
dstate(0x1F, 6); /* 011111 -> Reset->Idle */
|
||||
|
||||
if(o != irlen)
|
||||
sysfatal("wrong tapchain irlen %d %d\n", o, irlen);
|
||||
|
||||
ndaps = 0;
|
||||
for(i=0; i<ntaps; i++){
|
||||
fprint(2, "tap%d: id=%.8ux off=%d len=%d delay=%d\n",
|
||||
i, taps[i].id, taps[i].off, taps[i].len, taps[i].delay);
|
||||
|
||||
switch(taps[i].id){
|
||||
case 0x4ba00477:
|
||||
o = 3;
|
||||
daps = realloc(daps, sizeof(daps[0]) * (ndaps+o));
|
||||
for(j=0; j<o; j++){
|
||||
daps[ndaps].tap = taps+i;
|
||||
daps[ndaps].port = j;
|
||||
daps[ndaps].id = apr(daps+ndaps, 0xFC);
|
||||
fprint(2, "\tdap%d: id=%.8ux\n", j, daps[ndaps].id);
|
||||
|
||||
ndaps++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<ndaps; i++){
|
||||
switch(daps[i].id){
|
||||
case 0x44770001:
|
||||
ahbap = daps+i;
|
||||
break;
|
||||
case 0x24770002:
|
||||
apbap = daps+i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum {
|
||||
DBGDIDR = 0x000,
|
||||
DBGDEVID = 0xFC8,
|
||||
DBGDSCR = 0x088,
|
||||
RXfull = 1<<30,
|
||||
TXfull = 1<<29,
|
||||
RXfull_1 = 1<<27,
|
||||
TXfull_1 = 1<<26,
|
||||
PipeAdv = 1<<25,
|
||||
InstrCompl_1 = 1<<24,
|
||||
ExtDCCmodeShift = 20,
|
||||
ExtDCCmodeMask = 3<<ExtDCCmodeShift,
|
||||
ADAdiscard = 1<<19,
|
||||
NS = 1<<18,
|
||||
SPNIDdis = 1<<17,
|
||||
SPIDdis = 1<<16,
|
||||
MDBGen = 1<<15,
|
||||
HDBGen = 1<<14,
|
||||
ITRen = 1<<13,
|
||||
UDCCdis = 1<<12,
|
||||
INTdis = 1<<11,
|
||||
DBGack = 1<<10,
|
||||
UND_1 = 1<<8,
|
||||
ADABORT_1 = 1<<7,
|
||||
SDABORT_1 = 1<<6,
|
||||
MOEShift = 2,
|
||||
MOEMask = 15<<MOEShift,
|
||||
RESTARTED = 1<<1,
|
||||
HALTED = 1<<0,
|
||||
|
||||
DBGDRCR = 0x90,
|
||||
RestartReq = 1<<1,
|
||||
HaltReq = 1<<0,
|
||||
|
||||
DBGPRCR = 0x310,
|
||||
|
||||
DBGITR = 0x084, /* Instruction Transfer Register */
|
||||
DBGDTRRX = 0x080, /* Host to Target Data Transfer Register */
|
||||
DBGDTRTX = 0x08C, /* Target to Host Data Transfer Register */
|
||||
};
|
||||
|
||||
typedef struct Arm Arm;
|
||||
struct Arm
|
||||
{
|
||||
u32int dbgbase;
|
||||
|
||||
Dap *dbgap;
|
||||
Dap *memap;
|
||||
|
||||
char *id;
|
||||
};
|
||||
Arm arm[2];
|
||||
u32int
|
||||
dbgr(Arm *arm, u32int reg)
|
||||
{
|
||||
return mmr(arm->dbgap, arm->dbgbase+reg);
|
||||
}
|
||||
void
|
||||
dbgw(Arm *arm, u32int reg, u32int val)
|
||||
{
|
||||
mmw(arm->dbgap, arm->dbgbase+reg, val);
|
||||
}
|
||||
u32int
|
||||
dbgrpoll(Arm *arm, u32int reg, u32int mask, u32int val)
|
||||
{
|
||||
u32int w;
|
||||
|
||||
for(;;){
|
||||
w = dbgr(arm, reg);
|
||||
if((w & mask) == val)
|
||||
break;
|
||||
}
|
||||
return w;
|
||||
}
|
||||
|
||||
void
|
||||
startstop(Arm *arm, int stop)
|
||||
{
|
||||
u32int s;
|
||||
|
||||
s = dbgr(arm, DBGDSCR);
|
||||
if((s & HALTED) != stop){
|
||||
if(!stop){
|
||||
s &= ~ITRen;
|
||||
dbgw(arm, DBGDSCR, s);
|
||||
}
|
||||
dbgw(arm, DBGDRCR, stop ? HaltReq : RestartReq);
|
||||
s = dbgrpoll(arm, DBGDSCR, HALTED, stop);
|
||||
if(stop){
|
||||
s |= ITRen;
|
||||
dbgw(arm, DBGDSCR, s);
|
||||
}
|
||||
fprint(2, "%s: startstop: %.8ux\n", arm->id, s);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
armxec(Arm *arm, u32int instr)
|
||||
{
|
||||
dbgw(arm, DBGITR, instr);
|
||||
dbgrpoll(arm, DBGDSCR, InstrCompl_1, InstrCompl_1);
|
||||
}
|
||||
|
||||
#define ARMV4_5_MRC(CP, op1, Rd, CRn, CRm, op2) \
|
||||
(0xee100010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
|
||||
| ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
|
||||
#define ARMV4_5_MCR(CP, op1, Rd, CRn, CRm, op2) \
|
||||
(0xee000010 | (CRm) | ((op2) << 5) | ((CP) << 8) \
|
||||
| ((Rd) << 12) | ((CRn) << 16) | ((op1) << 21))
|
||||
|
||||
void
|
||||
trrxw(Arm *arm, u32int val)
|
||||
{
|
||||
dbgrpoll(arm, DBGDSCR, RXfull_1, 0);
|
||||
dbgw(arm, DBGDTRRX, val);
|
||||
}
|
||||
u32int
|
||||
trtxr(Arm *arm)
|
||||
{
|
||||
dbgrpoll(arm, DBGDSCR, TXfull_1, TXfull_1);
|
||||
return dbgr(arm, DBGDTRTX);
|
||||
}
|
||||
|
||||
void
|
||||
armrw(Arm *arm, int reg, u32int val);
|
||||
|
||||
u32int
|
||||
armrr(Arm *arm, int rn)
|
||||
{
|
||||
if(rn == 15){
|
||||
u32int r0;
|
||||
|
||||
r0 = armrr(arm, 0);
|
||||
armxec(arm, 0xE1A0000F);
|
||||
armxec(arm, ARMV4_5_MCR(14, 0, 0, 0, 5, 0));
|
||||
armrw(arm, 0, r0);
|
||||
} else {
|
||||
armxec(arm, ARMV4_5_MCR(14, 0, rn, 0, 5, 0));
|
||||
}
|
||||
return trtxr(arm);
|
||||
}
|
||||
void
|
||||
armrw(Arm *arm, int rn, u32int val)
|
||||
{
|
||||
if(rn == 15){
|
||||
u32int r0;
|
||||
|
||||
r0 = armrr(arm, 0);
|
||||
armrw(arm, 0, val);
|
||||
armxec(arm, 0xE1A0F000);
|
||||
armrw(arm, 0, r0);
|
||||
} else {
|
||||
trrxw(arm, val);
|
||||
armxec(arm, ARMV4_5_MRC(14, 0, rn, 0, 5, 0));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* mww phys 0xf8000008 0xdf0d
|
||||
* mww phys 0xf8000910 0xf
|
||||
* load_image "/sys/src/boot/zynq/fsbl" 0xfffc0000 bin
|
||||
* reg pc 0xfffc0000
|
||||
*/
|
||||
void
|
||||
boot(char *file, u32int entry)
|
||||
{
|
||||
u32int *buf, *src;
|
||||
int fd, size;
|
||||
u32int dst;
|
||||
|
||||
fprint(2, "load %s", file);
|
||||
if((fd = open(file, OREAD)) < 0)
|
||||
sysfatal("open: %r");
|
||||
|
||||
size = seek(fd, 0, 2);
|
||||
fprint(2, " [%ud]", size);
|
||||
seek(fd, 0, 0);
|
||||
buf = malloc((size+3) & ~3);
|
||||
if(readn(fd, buf, size) != size)
|
||||
sysfatal("read: %r");
|
||||
close(fd);
|
||||
|
||||
/* map ocm */
|
||||
mmw(arm->memap, 0xf8000008, 0xdf0d);
|
||||
mmw(arm->memap, 0xf8000910, 0xf);
|
||||
|
||||
src = buf;
|
||||
for(dst = entry; size > 0; dst += 4, size -= 4){
|
||||
if((dst & 0xF) == 0)
|
||||
fprint(2, ".");
|
||||
mmw(arm->memap, dst, *src++);
|
||||
}
|
||||
free(buf);
|
||||
fprint(2, ".\nentry %.8ux\n", entry);
|
||||
|
||||
armrw(arm, 15, entry);
|
||||
}
|
||||
|
||||
void
|
||||
usage(void)
|
||||
{
|
||||
fprint(2, "%s [ -j jtagdev ] entry image\n", argv0);
|
||||
exits("usage");
|
||||
}
|
||||
|
||||
void
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
char *jtag = "/dev/jtagddd94.0";
|
||||
char *image;
|
||||
u32int entry;
|
||||
|
||||
fmtinstall('H', encodefmt);
|
||||
|
||||
ARGBEGIN {
|
||||
case 'j':
|
||||
jtag = EARGF(usage());
|
||||
break;
|
||||
default:
|
||||
usage();
|
||||
} ARGEND;
|
||||
|
||||
if(argc != 2)
|
||||
usage();
|
||||
entry = strtoul(argv[0], nil, 0);
|
||||
image = argv[1];
|
||||
|
||||
ioinit(jtag);
|
||||
tapreset();
|
||||
|
||||
arm[0].dbgbase = 0x80090000;
|
||||
arm[0].dbgap = apbap;
|
||||
arm[0].memap = ahbap;
|
||||
arm[0].id = "arm0";
|
||||
|
||||
arm[1].dbgbase = 0x80092000;
|
||||
arm[1].dbgap = apbap;
|
||||
arm[1].memap = ahbap;
|
||||
arm[1].id = "arm1";
|
||||
|
||||
startstop(arm+0, 1);
|
||||
startstop(arm+1, 1);
|
||||
|
||||
boot(image, entry);
|
||||
|
||||
startstop(arm+0, 0);
|
||||
startstop(arm+1, 0);
|
||||
|
||||
exits(nil);
|
||||
}
|
|
@ -2,25 +2,29 @@ objtype=arm
|
|||
</$objtype/mkfile
|
||||
BIN=/arm
|
||||
TARG=fsbl fsbl.img
|
||||
CLEANFILES=boothead.$cputype
|
||||
FSBLFILES=fsbl.$O ddr.$O main.$O mmc.$O net.$O div.$O qspi.$O
|
||||
TEXTBASE=0xfffc0000
|
||||
|
||||
all:V: $TARG
|
||||
|
||||
clean:V:
|
||||
rm -rf $TARG *.$O
|
||||
@{objtype=$cputype mk -f mkfile.port clean}
|
||||
|
||||
fsbl: $FSBLFILES
|
||||
$LD -o $target -T0xfffc0000 -H6 -R4096 -l -s $prereq
|
||||
$LD -o $target -T$TEXTBASE -H6 -R4096 -l -s $prereq
|
||||
|
||||
9fsbl: $FSBLFILES
|
||||
$LD -o $target -T0xfffc0000 -l $prereq
|
||||
$LD -o $target -T$TEXTBASE -l $prereq
|
||||
|
||||
fsbl.img:D: fsbl boothead.$cputype
|
||||
boothead.$cputype fsbl >fsbl.img
|
||||
|
||||
boothead.$cputype:V: mkfile.boothead
|
||||
@{objtype=$cputype mk -f $prereq all}
|
||||
%.$cputype:V: mkfile.port
|
||||
@{objtype=$cputype mk -f $prereq $target}
|
||||
|
||||
jtagload:V: fsbl jtagload.$cputype
|
||||
./jtagload.$cputype -j /dev/jtag*.0 $TEXTBASE fsbl
|
||||
|
||||
div.$O: /sys/src/libc/arm/div.s
|
||||
$AS /sys/src/libc/arm/div.s
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
</$objtype/mkfile
|
||||
|
||||
all:V: boothead.$objtype
|
||||
|
||||
boothead.$objtype: boothead.$O
|
||||
$LD $LDFLAGS -o $target $prereq
|
||||
|
||||
%.$O: %.c
|
||||
$CC $CFLAGS $stem.c
|
14
sys/src/boot/zynq/mkfile.port
Normal file
14
sys/src/boot/zynq/mkfile.port
Normal file
|
@ -0,0 +1,14 @@
|
|||
</$objtype/mkfile
|
||||
|
||||
TARG=boothead.$objtype jtagload.$objtype
|
||||
|
||||
all:V: $TARG
|
||||
|
||||
clean:V:
|
||||
rm -f $TARG *.$O
|
||||
|
||||
%.$objtype: %.$O
|
||||
$LD $LDFLAGS -o $target $prereq
|
||||
|
||||
%.$O: %.c
|
||||
$CC $CFLAGS $stem.c
|
Loading…
Reference in a new issue