summaryrefslogtreecommitdiff
path: root/utils/ql/asm.c
diff options
context:
space:
mode:
Diffstat (limited to 'utils/ql/asm.c')
-rw-r--r--utils/ql/asm.c104
1 files changed, 101 insertions, 3 deletions
diff --git a/utils/ql/asm.c b/utils/ql/asm.c
index 25d4c772..be1a57a1 100644
--- a/utils/ql/asm.c
+++ b/utils/ql/asm.c
@@ -1,6 +1,7 @@
#include "l.h"
#define KMASK 0xF0000000
+#define JMPSZ sizeof(u32int) /* size of bootstrap jump section */
#define LPUT(c)\
{\
@@ -50,12 +51,15 @@ asmb(void)
Prog *p;
long t;
Optab *o;
+ long prevpc;
if(debug['v'])
Bprint(&bso, "%5.2f asm\n", cputime());
Bflush(&bso);
+
+ /* emit text segment */
seek(cout, HEADR, 0);
- pc = INITTEXT;
+ prevpc = pc = INITTEXT;
for(p = firstp; p != P; p = p->link) {
if(p->as == ATEXT) {
curtext = p;
@@ -79,14 +83,32 @@ asmb(void)
pc += 4;
}
pc += o->size;
+ if (prevpc & (1<<31) && (pc & (1<<31)) == 0) {
+ char *tn;
+
+ tn = "?none?";
+ if(curtext != P && curtext->from.sym != S)
+ tn = curtext->from.sym->name;
+ Bprint(&bso, "%s: warning: text segment wrapped past 0\n", tn);
+ }
+ prevpc = pc;
}
+ /* for virtex 4, inject a jmp instruction after other text */
+ if(HEADTYPE == 6)
+ /* branch to absolute entry address (0xfffe2100) */
+ lput((18 << 26) | (0x03FFFFFC & entryvalue()) | 2);
+
if(debug['a'])
Bprint(&bso, "\n");
Bflush(&bso);
cflush();
+ /* emit data segment */
curtext = P;
switch(HEADTYPE) {
+ case 6:
+ textsize += JMPSZ;
+ /* fall through */
case 0:
case 1:
case 2:
@@ -126,6 +148,7 @@ asmb(void)
case 1:
case 2:
case 5:
+ case 6:
seek(cout, HEADR+textsize+datsize, 0);
break;
case 3:
@@ -154,6 +177,7 @@ asmb(void)
cflush();
}
+ /* back up and write the header */
seek(cout, 0L, 0);
switch(HEADTYPE) {
case 0:
@@ -290,6 +314,10 @@ asmb(void)
lput(0x80L); /* flags */
break;
case 5:
+ /*
+ * customised for blue/gene,
+ * notably the alignment and KMASK masking.
+ */
strnput("\177ELF", 4); /* e_ident */
CPUT(1); /* class = 32 bit */
CPUT(2); /* data = MSB */
@@ -335,8 +363,8 @@ asmb(void)
lput(0L); /* data - type = PT_NULL */
lput(HEADR+textsize+datsize); /* file offset */
- lput(0L);
- lput(0L);
+ lput(0L); /* vaddr */
+ lput(0L); /* paddr */
lput(symsize); /* symbol table size */
lput(lcsize); /* line number size */
lput(0x04L); /* protections = R */
@@ -392,6 +420,76 @@ asmb(void)
cput(0);
break;
+ case 6:
+ /*
+ * customised for virtex 4 boot,
+ * notably the alignment and KMASK masking.
+ */
+ strnput("\177ELF", 4); /* e_ident */
+ CPUT(1); /* class = 32 bit */
+ CPUT(2); /* data = MSB */
+ CPUT(1); /* version = CURRENT */
+ strnput("", 9);
+ lput((2L<<16)|20L); /* type = EXEC; machine = PowerPC */
+ lput(1L); /* version = CURRENT */
+ lput(entryvalue()); /* entry vaddr */
+ lput(52L); /* offset to first phdr */
+
+ debug['S'] = 1; /* no symbol table */
+ if(debug['S']){
+ lput(HEADR+textsize+datsize+symsize); /* offset to first shdr */
+ lput(0L); /* flags = PPC */
+ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
+ lput((4L<<16)|40L); /* # Phdrs & Shdr size */
+ lput((4L<<16)|2L); /* # Shdrs & shdr string size */
+ }
+ else{
+ lput(0L);
+ lput(0L); /* flags = PPC */
+ lput((52L<<16)|32L); /* Ehdr & Phdr sizes*/
+ lput((4L<<16)|0L); /* # Phdrs & Shdr size */
+ lput((4L<<16)|0L); /* # Shdrs & shdr string size */
+ }
+
+ lput(1L); /* text - type = PT_LOAD */
+ lput(HEADR); /* file offset */
+ lput(INITTEXT); /* vaddr */
+ lput(INITTEXT); /* paddr */
+ lput(textsize-JMPSZ); /* file size */
+ lput(textsize-JMPSZ); /* memory size */
+ lput(0x05L); /* protections = RX */
+ lput(0); /* alignment */
+
+ lput(1L); /* data - type = PT_LOAD */
+ lput(HEADR+textsize); /* file offset */
+ lput(INITDAT); /* vaddr */
+ lput(INITDAT); /* paddr */
+ lput(datsize); /* file size */
+ lput(datsize+bsssize); /* memory size */
+ lput(0x07L); /* protections = RWX */
+ lput(0); /* alignment */
+
+ lput(0L); /* data - type = PT_NULL */
+ lput(HEADR+textsize+datsize); /* file offset */
+ lput(0L); /* vaddr */
+ lput(0L); /* paddr */
+ lput(symsize); /* symbol table size */
+ lput(lcsize); /* line number size */
+ lput(0x04L); /* protections = R */
+ lput(0x04L); /* alignment code?? */
+
+ /* add tiny text section at end with jmp to start */
+ lput(1L); /* text - type = PT_LOAD */
+ lput(HEADR+textsize-JMPSZ); /* file offset */
+ lput(0xFFFFFFFC); /* vaddr */
+ lput(0xFFFFFFFC); /* paddr */
+ lput(JMPSZ); /* file size */
+ lput(JMPSZ); /* memory size */
+ lput(0x05L); /* protections = RX */
+ lput(0); /* disable alignment */
+
+ cflush();
+ break;
}
cflush();
}