1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261 |
- MODULE O7ARMv7MLinker;
- (* Link and load on RISC; NW 20.10.2013 / 8.1.2019 *)
- (* ARMv7-M: Alexander Shiryaev, 2014.10, 2015.02, 2016.06, 2017.01, 2019.11, 2021.08 *)
- (*
- TODO:
- procedure addresses (progbase-relative...)
- add support of version-0 files
- resource files (simple copy to flashOrg before all)
- NOTES:
- we do not fill global data by zeros
- do not call GC.Collect before all global pointers initialization!
- pointer references for GC only
- MTab stored in RAM for fast access
- modules ptrs table stored in RAM for fast GC work
- *)
- IMPORT SYSTEM, Files (*:= O7Files*), Texts (*:= O7Texts*), Oberon (*:= O7Oberon*), ARMv6M := O7ARMv6M, ARMv7M := O7ARMv7M;
- TYPE
- LONGINT = INTEGER;
- BYTE = CHAR;
- CONST versionkey = 1X; MT = 6; SB = 3;
- trace = FALSE;
- (* fixup tags *)
- tagFixup = 00FFFFFFH; (* Add/Ldr/LdrB/Str/StrB *)
- tagVLDR = 00FFFFFCH;
- tagBL = 00FFFFE0H;
- tagLdrSB = 00FFFFD0H;
- TYPE Module = POINTER TO ModDesc;
- ModuleName = ARRAY 32 OF CHAR;
- ModDesc = RECORD
- name: ModuleName;
- next: Module;
- key, num: INTEGER;
- data: INTEGER; (* address, relative to mem, bytes *)
- strs: INTEGER; (* address, relative to data, bytes *)
- code: INTEGER; (* address, relative to flash start, halfwords *)
- entries: POINTER TO ARRAY OF INTEGER;
- entriesLen: INTEGER;
- imports: ARRAY 255 OF Module;
- body: INTEGER;
- typeds: POINTER TO ARRAY OF INTEGER;
- typedsLen: INTEGER;
- strings: POINTER TO ARRAY OF INTEGER;
- stringsLen: INTEGER;
- fixorgT: INTEGER;
- nPtrs: INTEGER; (* number of pointer references *)
- ptr: INTEGER (* address, relative to flash start, halfwords *)
- END;
- TargetName = ARRAY 32 OF CHAR;
- Target = POINTER TO RECORD
- next: Target;
- name: TargetName;
- isNXP: BOOLEAN;
- flashStart, flashSize: INTEGER;
- maxExtInts, flashOrg: INTEGER;
- SRAMStart, SRAMSize: INTEGER
- END;
- VAR
- root: Module;
- modules: ARRAY 100H OF Module;
- flash: ARRAY 200000H DIV 2 OF INTEGER; flashW: INTEGER;
- memW: INTEGER; (* bytes *)
- nPtrs: INTEGER;
- res*: INTEGER;
- importing, imported: ModuleName;
- W: Texts.Writer;
- target: Target;
- targets: Target;
- PROCEDURE BITS (x: INTEGER): SET;
- BEGIN
- RETURN SYSTEM.VAL(SET, x)
- END BITS;
- PROCEDURE ORDSET (x: SET): INTEGER;
- BEGIN
- RETURN SYSTEM.VAL(INTEGER, x)
- END ORDSET;
- PROCEDURE StrLen (VAR x: ARRAY OF CHAR): INTEGER;
- VAR i: INTEGER;
- BEGIN
- i := 0;
- WHILE (i < LEN(x)) & (x[i] # 0X) DO INC(i) END;
- RETURN i
- END StrLen;
- PROCEDURE CmpStr (VAR a, b: ARRAY OF CHAR): BOOLEAN;
- VAR i: INTEGER;
- res: BOOLEAN;
- BEGIN
- i := 0;
- WHILE (i < LEN(a)) & (i < LEN(b)) & (a[i] # 0X) & (b[i] # 0X) & (a[i] = b[i]) DO INC(i) END;
- res := (i = LEN(a)) OR (i = LEN(b)) OR ((a[i] = 0X) & (b[i] = 0X));
- RETURN res
- END CmpStr;
- PROCEDURE ReadInt (VAR R: Files.Rider; VAR x: INTEGER);
- VAR y: SYSTEM.INT64;
- BEGIN
- Files.ReadLInt(R, y);
- IF R.eof THEN x := -1
- ELSE x := SHORT(y)
- END
- END ReadInt;
- PROCEDURE ThisFile ((*IN*) VAR name: ARRAY OF CHAR): Files.File;
- VAR i: INTEGER;
- filename: ModuleName;
- BEGIN i := 0;
- WHILE name[i] # 0X DO filename[i] := name[i]; INC(i) END ;
- filename[i] := "."; filename[i+1] := "a"; filename[i+2] := "7";
- filename[i+3] := "m"; filename[i+4] := 0X;
- RETURN Files.Old(filename)
- END ThisFile;
- PROCEDURE NewHexFile ((*IN*) VAR name: ARRAY OF CHAR): Files.File;
- VAR i: INTEGER;
- filename: ModuleName;
- BEGIN i := 0;
- WHILE name[i] # 0X DO filename[i] := name[i]; INC(i) END ;
- filename[i] := "."; filename[i+1] := "h"; filename[i+2] := "e";
- filename[i+3] := "x"; filename[i+4] := 0X;
- RETURN Files.New(filename)
- END NewHexFile;
- PROCEDURE NewBinFile ((*IN*) VAR name: ARRAY OF CHAR): Files.File;
- VAR i: INTEGER;
- filename: ModuleName;
- BEGIN i := 0;
- WHILE name[i] # 0X DO filename[i] := name[i]; INC(i) END ;
- filename[i] := "."; filename[i+1] := "b"; filename[i+2] := "i";
- filename[i+3] := "n"; filename[i+4] := 0X;
- RETURN Files.New(filename)
- END NewBinFile;
- PROCEDURE error (n: INTEGER; (*IN*) VAR name: ARRAY OF CHAR);
- BEGIN res := n; COPY(name, importing)
- END error;
- PROCEDURE Check ((*IN*) VAR s: ARRAY OF CHAR);
- VAR i: INTEGER; ch: CHAR;
- BEGIN ch := s[0]; res := 1; i := 1;
- IF (ch >= "A") & (ch <= "Z") OR (ch >= "a") & (ch <= "z") THEN
- REPEAT ch := s[i]; INC(i)
- UNTIL ~((ch >= "0") & (ch <= "9") OR (ch >= "A") & (ch <= "Z")
- OR (ch >= "a") & (ch <= "z") OR (ch = ".")) OR (i = 32);
- IF (i < 32) & (ch = 0X) THEN res := 0 END
- END
- END Check;
- (* emit 2 instructions *)
- PROCEDURE EmitADDSIm0 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; a, b, im: INTEGER);
- CONST S = 1;
- VAR i, imm3, imm8: INTEGER; isMI: BOOLEAN;
- BEGIN
- ARMv7M.EncodeMI12(im, i, imm3, imm8, isMI);
- IF isMI THEN
- ASSERT(b # 15, 100);
- ASSERT((b = 13) OR (a # 13), 101);
- (* A7.7.3: ADD (immediate); encoding T3 ARMv7-M *)
- (* A7.7.5: ADD (SP plus immediate); encoding T3 ARMv7-M *)
- ARMv7M.EmitDPMI(code, pc, i, 16 + S, b, imm3, a, imm8)
- ELSIF im <= 255 + 7 THEN
- ARMv6M.EmitADDSIm(code, pc, a, b, 7);
- ARMv6M.EmitADDSIm(code, pc, a, a, im - 7)
- ELSE HALT(1)
- (* fixup failed: offset is too big
- (implementation limit) *)
- END
- END EmitADDSIm0;
- (* search module in list; if not found, load module *)
- PROCEDURE Load ((*IN*) VAR name: ARRAY OF CHAR; VAR newmod: Module);
- VAR mod, impmod: Module;
- i, n, key, impkey, mno, nofimps, size: INTEGER;
- u, v, w: INTEGER; (*addresses*)
- ch: CHAR;
- fixorgP, fixorgD: INTEGER;
- disp, adr, inst, pno, vno, dest, offset: INTEGER;
- name1, impname: ModuleName;
- F: Files.File; R: Files.Rider;
- import: ARRAY 255 OF Module;
- a, b: INTEGER;
- op: INTEGER; (* 0: LW, 1: LB, 2: ADDS, 3: SW, 4: SB, 5: VLDR *)
- nxt: INTEGER;
- ok: BOOLEAN;
- BEGIN
- mod := root; error(0, name); nofimps := 0;
- WHILE (mod # NIL) & ~CmpStr(name, mod.name) DO mod := mod.next END;
- IF mod = NIL THEN (*load*)
- Check(name);
- IF res = 0 THEN F := ThisFile(name) ELSE F := NIL END;
- IF F # NIL THEN
- Files.Set(R, F, 0); Files.ReadString(R, name1);
- ReadInt(R, key); Files.Read(R, ch);
- ReadInt(R, size); importing := name1;
- IF ch = versionkey THEN
- Files.ReadString(R, impname); (*imports*)
- WHILE (impname[0] # 0X) & (res = 0) DO
- ReadInt(R, impkey);
- Load(impname, impmod);
- import[nofimps] := impmod; importing := name1;
- IF res = 0 THEN
- IF impmod.key = impkey THEN INC(nofimps)
- ELSE error(3, name1); imported := impname
- END
- END;
- Files.ReadString(R, impname)
- END
- ELSE error(2, name1)
- END
- ELSE error(1, name(*$*))
- END;
- IF res = 0 THEN NEW(mod); mod.next := root;
- IF root = NIL THEN mod.num := 0
- ELSE mod.num := root.num + 1
- END;
- root := mod
- END;
- IF res = 0 THEN (*read file*)
- COPY(name, mod.name); mod.key := key;
- mod.data := memW;
- modules[mod.num] := mod;
- (* type descriptors *)
- ReadInt(R, n); ASSERT(n MOD 4 = 0, 100);
- INC(memW, n);
- n := n DIV 4;
- IF n > 0 THEN NEW(mod.typeds, n) END;
- mod.typedsLen := n;
- i := 0;
- WHILE n > 0 DO ReadInt(R, w);
- mod.typeds[i] := w; INC(i);
- DEC(n)
- END;
- (* variable space *)
- ReadInt(R, n); INC(memW, n);
- (* strings *)
- mod.strs := memW - mod.data;
- ReadInt(R, n); ASSERT(n MOD 4 = 0, 101);
- INC(memW, n);
- n := n DIV 4;
- IF n > 0 THEN NEW(mod.strings, n) END;
- mod.stringsLen := n;
- i := 0;
- WHILE n > 0 DO ReadInt(R, w);
- mod.strings[i] := w; INC(i);
- DEC(n)
- END;
- (* program *)
- IF ODD(flashW) THEN
- (* align, required for modules with
- "LDR r, [pc, offset]" instructions, pc must be multiple of 4;
- used for constants loading *)
- ARMv6M.EmitNOP(flash, flashW)
- END;
- mod.code := flashW;
- (* program code *)
- ReadInt(R, n);
- WHILE n > 0 DO ReadInt(R, w);
- flash[flashW] := w; INC(flashW);
- DEC(n)
- END;
- (* copy imports *)
- i := 0;
- WHILE i < nofimps DO
- mod.imports[i] := import[i];
- INC(i)
- END;
- (* skip commands *)
- Files.Read(R, ch);
- WHILE ch # 0X DO
- REPEAT Files.Read(R, ch) UNTIL ch = 0X; ReadInt(R, n);
- Files.Read(R, ch)
- END;
- (* entries *)
- ReadInt(R, n);
- NEW(mod.entries, n); mod.entriesLen := n; i := 0;
- WHILE n > 0 DO ReadInt(R, w);
- mod.entries[i] := w; INC(i);
- DEC(n)
- END;
- (* pointer references *)
- mod.nPtrs := 0;
- ReadInt(R, w);
- IF (w >= 0) & ODD(flashW) THEN (* align *)
- flash[flashW] := 0; INC(flashW)
- END;
- mod.ptr := flashW;
- WHILE w >= 0 DO
- ASSERT(w < mod.strs, 100);
- flash[flashW] := mod.data + w; (* will be fixed up in Link1 *)
- INC(flashW, 2); INC(mod.nPtrs);
- ReadInt(R, w)
- END;
- IF mod.nPtrs # 0 THEN
- flash[flashW] := 0; INC(flashW);
- flash[flashW] := 0; INC(flashW);
- INC(nPtrs)
- END;
- ReadInt(R, fixorgP);
- ReadInt(R, fixorgD);
- ReadInt(R, mod.fixorgT);
- (* entry point *)
- ReadInt(R, w); ASSERT(w MOD 4 = 0, 100);
- mod.body := mod.code + w DIV 4;
- Files.Read(R, ch);
- IF ch # "O" THEN (* corrupted file *) mod := NIL; error(4, name(*$*)) END
- END;
- IF res = 0 THEN
- (* fixup of BL *)
- adr := mod.code + fixorgP;
- WHILE adr # mod.code DO
- inst := flash[adr];
- ASSERT(inst DIV 10H * 10H = tagBL);
- a := inst MOD 10H;
- DEC(adr);
- inst := flash[adr];
- ASSERT(inst DIV 1000000H MOD 100H = 0F7H, 101); (* BL *)
- mno := inst DIV 100000H MOD 10H + a * 10H;
- pno := inst DIV 1000H MOD 100H;
- disp := inst MOD 1000H;
- impmod := mod.imports[mno-1];
- dest := impmod.entries[pno];
- ASSERT(dest MOD 4 = 0, 102); dest := dest DIV 4;
- dest := dest + impmod.code;
- offset := dest - adr - 1;
- i := adr; ARMv6M.EmitBL(flash, i, offset - 1);
- adr := adr - disp
- END;
- (* fixup of LDR/STR/ADD *)
- adr := (mod.code + fixorgD) * 4;
- WHILE adr DIV 4 # mod.code DO
- inst := flash[adr DIV 4];
- mno := inst DIV 100000H MOD 10H;
- disp := inst MOD 1000H;
- a := inst DIV 1000000H MOD 10H;
- ASSERT(a = SB, 103);
- ASSERT(inst DIV 10000000H MOD 10H = 8, 103); (* Ldr *)
- ASSERT(flash[adr DIV 4 + 1] DIV 10H * 10H = tagLdrSB);
- mno := mno + flash[adr DIV 4 + 1] MOD 10H * 10H;
- IF mno = 0 THEN (* global *)
- i := adr DIV 4;
- ARMv7M.EmitLWImW(flash, i, a, MT, mod.num * 4)
- ELSE (* import *)
- impmod := mod.imports[mno-1]; v := impmod.num;
- i := adr DIV 4; ARMv7M.EmitLWImW(flash, i, a, MT, v * 4);
- inst := flash[adr DIV 4 + 2];
- vno := inst MOD 100H;
- a := inst DIV 1000000H MOD 10H;
- b := inst DIV 100000H MOD 10H; ASSERT(b = SB, 100);
- nxt := flash[adr DIV 4 + 3];
- CASE inst DIV 10000000H MOD 10H OF 4:
- ASSERT(nxt = tagFixup);
- IF inst DIV 10000H MOD 10H = 8 (* Add *) THEN op := 2
- ELSE HALT(1)
- END
- | 8: (* Ldr *)
- IF nxt = tagFixup THEN op := 0
- ELSIF nxt = tagVLDR THEN op := 5
- ELSE HALT(2)
- END
- | 9: (* LdrB *)
- ASSERT(nxt = tagFixup);
- op := 1
- | 10: (* Str *)
- ASSERT(nxt = tagFixup);
- op := 3
- | 11: (* StrB *)
- ASSERT(nxt = tagFixup);
- op := 4
- END;
- offset := impmod.entries[vno];
- IF ODD(inst DIV 100H) THEN
- ASSERT(offset MOD 4 = 0);
- offset := offset DIV 2; (* now offset in bytes *)
- offset := offset + impmod.code * 2;
- HALT(126);
- offset := offset - impmod.data
- END;
- i := adr DIV 4 + 2;
- CASE op OF 0: ASSERT(offset MOD 4 = 0, 100);
- ARMv7M.EmitLWImW(flash, i, a, b, offset)
- | 1: ARMv7M.EmitLBImW(flash, i, a, b, offset)
- | 2: ASSERT(a # b, 102);
- EmitADDSIm0(flash, i, a, b, offset)
- | 3: ASSERT(offset MOD 4 = 0, 126);
- ARMv7M.EmitSWImW(flash, i, a, b, offset)
- | 4: ARMv7M.EmitSBImW(flash, i, a, b, offset)
- | 5: ASSERT(offset MOD 4 = 0);
- ARMv7M.EmitVLDR(flash, i, a, b, 1, offset DIV 4)
- END
- END;
- adr := adr - disp * 4
- END
- (* fixup of type descriptors will be made in Link1 *)
- ELSIF res >= 3 THEN COPY(name, importing);
- WHILE nofimps > 0 DO DEC(nofimps) END
- END
- END;
- newmod := mod
- END Load;
- PROCEDURE WriteIHEX32 ((*IN*) VAR name: ARRAY OF CHAR; (*IN*) VAR code: ARRAY OF INTEGER; codeLen: INTEGER; startAdr: INTEGER; SLA: INTEGER; (*OUT*) VAR ok: BOOLEAN);
- CONST maxRecLen = 16; (* <= 255 *)
- (*
- FlashMagic 7.50.3174 incorrectly handles hex files
- with maxRecLen = 255 (actually 252)
- Astrobe produces hex files with maxRecLen = 16
- *)
- VAR F: Files.File; R: Files.Rider;
- a: ARRAY 1 + 2 + 1 + maxRecLen + 1 OF INTEGER;
- r, offset, i: INTEGER;
- PROCEDURE WriteRec;
- VAR cs: INTEGER;
- PROCEDURE WriteH (x: INTEGER);
- PROCEDURE H (x: INTEGER);
- BEGIN
- IF x < 10 THEN Files.Write(R, CHR(x + ORD('0')))
- ELSE Files.Write(R, CHR(x - 10 + ORD('A')))
- END
- END H;
- BEGIN
- ASSERT(x >= 0, 20);
- ASSERT(x < 100H, 21);
- H(x DIV 10H); H(x MOD 10H)
- END WriteH;
- BEGIN
- Files.Write(R, ':');
- cs := 0;
- i := 0;
- WHILE i < 1 + 2 + 1 + a[0] DO
- WriteH(a[i]); cs := cs + a[i];
- INC(i)
- END;
- WriteH((-cs) MOD 100H);
- Files.Write(R, 0DX); Files.Write(R, 0AX)
- END WriteRec;
- PROCEDURE WriteELA (adr: INTEGER);
- BEGIN
- ASSERT(adr >= 0, 20);
- ASSERT(adr < 10000H, 21);
- a[0] := 2; (* len *)
- a[1] := 0; a[2] := 0; (* offset *)
- a[3] := 4; (* type: extended linear address *)
- a[4] := adr DIV 100H;
- a[5] := adr MOD 100H;
- WriteRec
- END WriteELA;
- BEGIN
- ASSERT(codeLen >= 0, 20);
- ASSERT(startAdr MOD 4 = 0, 21);
- F := NewHexFile(name);
- IF F # NIL THEN
- Files.Set(R, F, 0);
- r := 0;
- IF codeLen > 0 THEN
- offset := startAdr MOD 10000H;
- startAdr := startAdr DIV 10000H MOD 10000H;
- WriteELA(startAdr);
- REPEAT
- a[0] := 0;
- a[1] := offset DIV 100H; a[2] := offset MOD 100H;
- a[3] := 0; (* type: data *)
- i := 0;
- WHILE (i <= maxRecLen - 2) & (offset <= 10000H - 2) & (codeLen > 0) DO
- a[4+i] := code[r] MOD 100H;
- a[5+i] := code[r] DIV 100H MOD 100H;
- ASSERT(code[r] DIV 10000H = 0, 100); (* all fixups done *)
- INC(a[0], 2);
- INC(r); DEC(codeLen);
- INC(i, 2);
- INC(offset, 2)
- END;
- WriteRec;
- IF (codeLen > 0) & (offset = 10000H) THEN
- INC(startAdr);
- WriteELA(startAdr);
- offset := 0
- END
- UNTIL codeLen = 0
- END;
- a[0] := 4; (* len *)
- a[1] := 0; a[2] := 0; (* offset *)
- a[3] := 5; (* type: start linear address *)
- a[4] := SLA DIV 1000000H MOD 100H;
- a[5] := SLA DIV 10000H MOD 100H;
- a[6] := SLA DIV 100H MOD 100H;
- a[7] := SLA MOD 100H;
- WriteRec;
- a[0] := 0; a[1] := 0; a[2] := 0; a[3] := 1 (* type: EOF *); WriteRec;
- Files.Register(F);
- ok := TRUE
- ELSE ok := FALSE
- END
- END WriteIHEX32;
- PROCEDURE WriteBin ((*IN*) VAR name: ARRAY OF CHAR; (*IN*) VAR code: ARRAY OF INTEGER; codeLen: INTEGER; (*OUT*) VAR ok: BOOLEAN);
- VAR F: Files.File; R: Files.Rider;
- r: INTEGER;
- BEGIN
- ASSERT(codeLen >= 0, 20);
- F := NewBinFile(name);
- IF F # NIL THEN
- Files.Set(R, F, 0); r := 0;
- WHILE codeLen > 0 DO
- ASSERT(code[r] DIV 10000H = 0, 100); (* all fixups done *)
- Files.Write(*Byte*)(R, CHR(code[r] MOD 100H));
- Files.Write(*Byte*)(R, CHR(code[r] DIV 100H));
- INC(r); DEC(codeLen)
- END;
- Files.Register(F); ok := TRUE
- ELSE ok := FALSE
- END
- END WriteBin;
- PROCEDURE opcode (VAR d: INTEGER; w: LONGINT);
- VAR s: ARRAY 64 OF CHAR;
- BEGIN
- ARMv6M.OpcodeRepr(d, w, s);
- IF s[0] # 0X THEN Texts.WriteString(W, s) END
- END opcode;
- (* R.a := im *)
- (* see ARMv7MG.MovIm *)
- PROCEDURE MovIm0 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; a: INTEGER; im: INTEGER);
- CONST S = 0;
- VAR shift: INTEGER;
- isLR: BOOLEAN;
- imInv: INTEGER; isMI: BOOLEAN; i, imm3, imm8, imm4: INTEGER;
- BEGIN
- ASSERT(a IN {0..14}, 21);
- isLR := a DIV 8 = 0;
- IF isLR & (im DIV 100H = 0) THEN
- ARMv6M.EmitMOVSIm(code, pc, a, im)
- ELSE
- ARMv7M.EncodeMI12(im, i, imm3, imm8, isMI);
- IF isMI THEN
- (* A7.7.75: MOV (immediate); encoding T2 ARMv7-M *)
- ARMv7M.EmitDPMI(code, pc, i, 4 + S, 0FH, imm3, a, imm8)
- (* S=1: N, Z, C will be updated *) (* NOTE: C *)
- ELSE
- imInv := ORDSET(BITS(im) / {0..31});
- ARMv7M.EncodeMI12(imInv, i, imm3, imm8, isMI);
- IF isMI THEN
- (* A7.7.84: MVN (immediate); encoding T1 ARMv7-M *)
- ARMv7M.EmitDPMI(code, pc, i, 6 + S, 0FH, imm3, a, imm8)
- (* S=1: N, Z, C will be updated *) (* NOTE: C *)
- ELSIF isLR & (im > 255) & (im <= 255 + 255) THEN
- ARMv6M.EmitMOVSIm(code, pc, a, 255);
- ARMv6M.EmitADDSIm(code, pc, a, a, im - 255)
- ELSE
- shift := 8;
- WHILE (shift < 32) & (SYSTEM.ROT(im DIV 100H * 100H, -shift) DIV 100H # 0) DO INC(shift) END;
- IF isLR & (shift < 32) THEN
- ASSERT(im =
- SYSTEM.LSH(SYSTEM.ROT(im DIV 100H * 100H, -shift), shift)
- + im MOD 100H);
- ARMv6M.EmitMOVSIm(code, pc, a, SYSTEM.ROT(im DIV 100H * 100H, -shift));
- ARMv6M.EmitLSLSIm(code, pc, a, a, shift);
- ARMv6M.EmitADDSIm(code, pc, a, a, im MOD 100H)
- ELSE
- (* TODO: 3 ops: mov; (add, lsl), (lsl, sub), (lsl, sub) | MI12; add, lsl, sub *)
- IF isLR & (im MOD 10000H DIV 100H = 0) THEN
- ARMv6M.EmitMOVSIm(code, pc, a, im MOD 10000H)
- ELSE
- (* A7.7.75: MOV (immediate); encoding T3 ARMv7-M *)
- imm4 := im DIV 1000H MOD 10H;
- i := im DIV 800H MOD 2;
- imm3 := im DIV 100H MOD 8;
- imm8 := im MOD 100H;
- ARMv7M.EmitDPPBI(code, pc, i, 4, imm4, imm3 * 1000H + a * 100H + imm8)
- END;
- im := im DIV 10000H;
- IF im # 0 THEN
- (* A7.7.78: MOVT; encoding T1 ARMv7 *)
- imm4 := im DIV 1000H MOD 10H;
- i := im DIV 800H MOD 2;
- imm3 := im DIV 100H MOD 8;
- imm8 := im MOD 100H;
- ARMv7M.EmitDPPBI(code, pc, i, 12, imm4, imm3 * 1000H + a * 100H + imm8)
- END
- END
- END
- END
- END
- END MovIm0;
- PROCEDURE SubIm0 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; d, n, im: INTEGER);
- BEGIN
- IF im DIV 8 = 0 THEN
- ARMv6M.EmitSUBSIm(code, pc, d, n, im)
- ELSE
- IF d # n THEN
- ARMv6M.EmitMOVSR(code, pc, d, n);
- END;
- ARMv6M.EmitSUBSIm(code, pc, d, d, im)
- END
- END SubIm0;
- PROCEDURE StrIm0 (VAR code: ARRAY OF INTEGER; VAR pc: INTEGER; t, n, im: INTEGER);
- BEGIN
- IF im DIV 32 = 0 THEN ARMv6M.EmitSTRIm(code, pc, t, n, im)
- ELSE ARMv7M.EmitSWImW(code, pc, t, n, im * 4)
- END
- END StrIm0;
- PROCEDURE Link1 ((*IN*) VAR name: ARRAY OF CHAR);
- VAR MTOrg, StkOrg, i, j: INTEGER;
- ok: BOOLEAN;
- mod, impmod: Module;
- adr, inst, mno, vno, disp, offset: INTEGER;
- r0, r1: INTEGER; r0a, r1a: BOOLEAN;
- BEGIN
- ASSERT(memW MOD 4 = 0, 100); (* should be aligned *)
- (* memW := (memW + 3) DIV 4 * 4; *) (* align *)
- MTOrg := target.SRAMStart + target.SRAMSize
- - (root.num + 1) * 4; (* MTab *)
- (* initial SP *)
- StkOrg := MTOrg - (nPtrs + 1) * 4 - memW;
- flash[0] := StkOrg MOD 10000H;
- flash[1] := StkOrg DIV 10000H MOD 10000H;
- (* reset vector *)
- inst := target.flashStart + flashW * 2 + 1;
- flash[2] := inst MOD 10000H;
- flash[3] := inst DIV 10000H MOD 10000H;
- (* CPU exceptions (NMI..SysTick) *)
- i := 4; WHILE i < 40H DIV 2 DO
- flash[i] := 1; INC(i);
- flash[i] := 0; INC(i)
- END;
- WHILE i < 40H DIV 2 + target.maxExtInts * 2 DO
- flash[i] := 1; INC(i);
- flash[i] := 0; INC(i)
- END;
- WHILE i < target.flashOrg DIV 2 DO
- flash[i] := 0; INC(i);
- flash[i] := 0; INC(i)
- END;
- IF target.isNXP THEN
- (* code read protection (CRP) *)
- flash[2FCH DIV 2] := 0; flash[2FCH DIV 2 + 1] := 0;
- (* NXP checksum *)
- j := 0; i := 0; WHILE i < 7 DO
- j := j + flash[2 * i] + 10000H * flash[2 * i + 1];
- INC(i)
- END;
- flash[2 * i] := (-j) MOD 10000H;
- flash[2 * i + 1] := (-j) DIV 10000H MOD 10000H
- END;
- IF memW > 0 THEN
- (* R[MT] := MTOrg *)
- MovIm0(flash, flashW, MT, MTOrg);
- (* modules ptrs table *)
- (* R[0] := MT - (nPtrs + 1) * 4 *)
- SubIm0(flash, flashW, 0, MT, (nPtrs + 1) * 4);
- i := 0; mod := root;
- WHILE mod # NIL DO
- IF mod.nPtrs # 0 THEN
- (* R[1] := flashStart + mod.ptr * 2 *)
- MovIm0(flash, flashW, 1,
- target.flashStart + mod.ptr * 2);
- (* Mem[R[0] + i * 4] := R[1] *)
- StrIm0(flash, flashW, 1, 0, i);
- INC(i)
- END;
- mod := mod.next
- END;
- ASSERT(i = nPtrs, 101);
- (* R[1] := i *)
- MovIm0(flash, flashW, 1, i);
- (* Mem[R[0] + i * 4] := R[1] *)
- StrIm0(flash, flashW, 1, 0, i);
- (* MT, type descriptors and strings *)
- j := 0;
- r0a := FALSE; r1a := FALSE;
- WHILE j <= root.num DO mod := modules[j];
- IF ~r0a OR (r0 # StkOrg + mod.data) THEN
- (* R[0] := StkOrg + mod.data *)
- MovIm0(flash, flashW, 0, StkOrg + mod.data);
- r0 := StkOrg + mod.data; r0a := TRUE
- END;
- (* MTab *)
- (* Mem[R[MT] + mod.num * 4] := R[0] *)
- StrIm0(flash, flashW, 0, MT, mod.num);
- (* fixup of type descriptors *)
- adr := mod.fixorgT * 4;
- WHILE adr DIV 4 # 0 DO
- inst := mod.typeds[adr DIV 4];
- IF trace THEN Texts.WriteLn(W);
- Texts.WriteString(W, "td fixup: ");
- Texts.WriteInt(W, adr DIV 4, 0);
- Texts.WriteHex(W, inst);
- Texts.WriteString(W, " -> ")
- END;
- mno := inst DIV 1000000H MOD 100H;
- vno := inst DIV 1000H MOD 1000H;
- disp := inst MOD 1000H;
- IF mno = 0 THEN (*global*) inst := StkOrg + mod.data + vno
- ELSE (*import*)
- impmod := mod.imports[mno-1];
- offset := impmod.entries[vno];
- inst := StkOrg + impmod.data + offset
- END;
- IF trace THEN Texts.WriteHex(W, inst) END;
- mod.typeds[adr DIV 4] := inst;
- adr := adr - disp * 4
- END;
- IF mod.typeds # NIL THEN (* type descriptors *)
- i := 0;
- WHILE i < mod.typedsLen DO
- IF ~r1a OR (r1 # mod.typeds[i]) THEN
- (* R[1] := mod.typeds[i] *)
- MovIm0(flash, flashW, 1, mod.typeds[i]);
- r1 := mod.typeds[i]; r1a := TRUE
- END;
- (* Mem[R[0] + i * 4] := R[1] *)
- StrIm0(flash, flashW, 1, 0, i);
- INC(i)
- END
- END;
- IF mod.strings # NIL THEN (* strings *)
- i := 0;
- WHILE i < mod.stringsLen DO
- IF ~r1a OR (r1 # mod.strings[i]) THEN
- (* R[1] := mod.strings[i] *)
- MovIm0(flash, flashW, 1, mod.strings[i]);
- r1 := mod.strings[i]; r1a := TRUE
- END;
- (* Mem[R[0] + mod.strs + i * 4] := R[1] *)
- ASSERT(mod.strs MOD 4 = 0);
- StrIm0(flash, flashW, 1, 0, mod.strs DIV 4 + i);
- INC(i)
- END
- END;
- (* fixup of pointer references *)
- i := 0;
- WHILE i < mod.nPtrs DO
- inst := StkOrg + flash[mod.ptr + i * 2];
- flash[mod.ptr + i * 2] := inst MOD 10000H;
- flash[mod.ptr + i * 2 + 1] := inst DIV 10000H MOD 10000H;
- INC(i)
- END;
- INC(j)
- END
- END;
- (* body calls *)
- i := 0;
- WHILE i <= root.num DO
- ARMv6M.EmitBL(flash, flashW, modules[i].body - flashW - 1 - 1);
- INC(i)
- END;
- (* stop *)
- ARMv6M.EmitB(flash, flashW, -1 - 1);
- IF ODD(flashW) THEN (* align *)
- ARMv6M.EmitNOP(flash, flashW)
- END;
- IF flashW * 2 <= target.flashSize THEN
- WriteIHEX32(name, flash, flashW,
- target.flashStart, target.flashStart + 1, ok);
- IF ~ok THEN res := 9 END;
- WriteBin(name, flash, flashW, ok);
- IF ~ok & (res = 0) THEN res := 10 END
- ELSE
- res := 8
- END
- END Link1;
- PROCEDURE Link*;
- VAR i: INTEGER;
- S: Texts.Scanner;
- mod: Module;
- d: INTEGER;
- BEGIN res := 0;
- Texts.OpenScanner(S, Oberon.Par.text, Oberon.Par.pos); Texts.Scan(S);
- IF (S.class = Texts.Name) OR (S.class = Texts.String) THEN
- target := targets;
- WHILE (target # NIL) & ~CmpStr(target.name, S.s) DO
- target := target.next
- END;
- IF target # NIL THEN
- Texts.Scan(S);
- IF S.class = Texts.Name THEN
- Texts.WriteString(W, "linking "); Texts.WriteString(W, S.s); Texts.WriteString(W, " ");
- root := NIL;
- flashW := target.flashOrg DIV 2;
- memW := 0;
- nPtrs := 0;
- Load(S.s, mod);
- IF res = 0 THEN Link1(S.s) END;
- CASE res OF 0:
- IF trace THEN Texts.WriteLn(W) END;
- Texts.WriteString(W, "Ok"); Texts.WriteLn(W);
- i := 0;
- WHILE i <= root.num DO mod := modules[i];
- Texts.Write(W, 9X);
- Texts.WriteString(W, mod.name);
- Texts.Write(W, 9X);
- Texts.WriteInt(W, mod.code, 0); Texts.WriteLn(W);
- INC(i)
- END;
- Texts.WriteString(W, "ROM: ");
- Texts.WriteInt(W, flashW * 2 (* - target.flashOrg *), 0);
- Texts.WriteString(W, " B; RAM: ");
- Texts.WriteInt(W,
- memW + (nPtrs + 1) * 4 + (root.num + 1) * 4, 0);
- Texts.WriteString(W, " B");
- IF trace THEN Texts.WriteLn(W);
- mod := root;
- WHILE mod # NIL DO
- Texts.WriteString(W, mod.name); Texts.WriteString(W, ":"); Texts.WriteLn(W);
- Texts.WriteString(W, " num: ");
- Texts.WriteInt(W, mod.num, 0); Texts.WriteLn(W);
- Texts.WriteString(W, " data: ");
- Texts.WriteInt(W, mod.data, 0); Texts.WriteLn(W);
- Texts.WriteString(W, " strs: ");
- Texts.WriteInt(W, mod.strs, 0); Texts.WriteLn(W);
- Texts.WriteString(W, " code: ");
- Texts.WriteInt(W, mod.code, 0); Texts.WriteLn(W);
- Texts.WriteString(W, " entries:");
- i := 0;
- WHILE i < mod.entriesLen DO
- Texts.Write(W, ' ');
- Texts.WriteInt(W, mod.entries[i], 0);
- INC(i)
- END;
- Texts.WriteLn(W);
- Texts.WriteString(W, " body: ");
- Texts.WriteInt(W, mod.body, 0); Texts.WriteLn(W);
- mod := mod.next
- END;
- i := 0; d := 0;
- WHILE i < flashW DO
- Texts.WriteInt(W, i, 4); Texts.Write(W, 9X);
- Texts.WriteHex(W, flash[i]); Texts.Write(W, 9X); opcode(d, flash[i]);
- Texts.WriteLn(W);
- INC(i)
- END;
- IF d # 0 THEN
- Texts.WriteString(W, "invalid decoder state");
- Texts.WriteLn(W)
- END
- END
- | 1: Texts.WriteString(W, "file not available: "); Texts.WriteString(W, importing)
- | 2: Texts.WriteString(W, "invalid version: "); Texts.WriteString(W, importing)
- | 3: Texts.WriteString(W, "key conflict: "); Texts.WriteString(W, importing); Texts.WriteString(W, ": "); Texts.WriteString(W, imported)
- | 4: Texts.WriteString(W, "corrupted file: "); Texts.WriteString(W, importing)
- | 7: Texts.WriteString(W, "no space: "); Texts.WriteString(W, importing)
- | 8: Texts.WriteString(W, "end of flash")
- | 9: Texts.WriteString(W, "write HEX failed")
- | 10: Texts.WriteString(W, "write BIN failed")
- END;
- Texts.WriteLn(W)
- END
- ELSE Texts.WriteString(W, "invalid target"); Texts.WriteLn(W);
- target := targets;
- WHILE target # NIL DO
- Texts.WriteString(W, target.name); Texts.WriteLn(W);
- target := target.next
- END
- END;
- Texts.Append(Oberon.Log, W.buf)
- END;
- (*Oberon.Collect(0)*)
- END Link;
- PROCEDURE EnterNXP ((*IN*) name: TargetName; maxExtInts, flashSize, SRAMSize, IAPReserve: INTEGER);
- VAR target: Target;
- BEGIN
- ASSERT(maxExtInts > 0, 20);
- ASSERT(maxExtInts <= 240 (* Cortex-M4 *), 21);
- ASSERT(flashSize MOD 4 = 0, 22);
- ASSERT(SRAMSize MOD 4 = 0, 23);
- NEW(target); target.next := targets; targets := target;
- target.name := name;
- target.isNXP := TRUE;
- target.flashStart := 0;
- target.maxExtInts := maxExtInts;
- target.flashOrg := (16 + maxExtInts) * 4;
- IF target.flashOrg <= 2FCH (* CRP *) THEN
- target.flashOrg := 2FCH (* CRP *) + 4
- END;
- target.flashSize := flashSize;
- target.SRAMStart := 10000000H;
- target.SRAMSize := SRAMSize - IAPReserve
- END EnterNXP;
- PROCEDURE EnterSTM ((*IN*) name0, fpo0, fpo1, suffix: ARRAY OF CHAR; maxExtInts, flashOrg, SRAMSize: INTEGER);
- VAR target: Target; i, j, k, l: INTEGER;
- BEGIN
- ASSERT(maxExtInts > 0, 20);
- ASSERT(maxExtInts <= 240 (* Cortex-M4 *), 21);
- ASSERT(flashOrg MOD 4 = 0, 22);
- ASSERT(flashOrg >= (16 + maxExtInts) * 4, 23);
- ASSERT(SRAMSize MOD 4 = 0, 24);
- i := 0;
- WHILE i < StrLen(fpo0) DO
- j := 0;
- WHILE j < StrLen(fpo1) DO
- NEW(target); target.next := targets; targets := target;
- target.name := name0(*$*); k := StrLen(target.name);
- target.name[k] := fpo0[i]; INC(k);
- target.name[k] := fpo1[j]; INC(k);
- l := 0;
- WHILE l < StrLen(suffix) DO
- target.name[k] := suffix[l]; INC(l); INC(k)
- END;
- target.name[k] := 0X;
- target.isNXP := FALSE;
- target.flashStart := 08000000H;
- target.maxExtInts := maxExtInts;
- target.flashOrg := flashOrg;
- IF fpo1[j] = '4' THEN target.flashSize := 4000H (* 16 KiB *)
- ELSIF fpo1[j] = '6' THEN target.flashSize := 8000H (* 32 KiB *)
- ELSIF fpo1[j] = '8' THEN target.flashSize := 10000H (* 64 KiB *)
- ELSIF fpo1[j] = 'B' THEN target.flashSize := 20000H (* 128 KiB *)
- ELSIF fpo1[j] = 'C' THEN target.flashSize := 40000H (* 256 KiB *)
- ELSIF fpo1[j] = 'D' THEN target.flashSize := 60000H (* 384 KiB *)
- ELSIF fpo1[j] = 'E' THEN target.flashSize := 80000H (* 512 KiB *)
- ELSIF fpo1[j] = 'F' THEN target.flashSize := 0C0000H (* 768 KiB *)
- ELSIF fpo1[j] = 'G' THEN target.flashSize := 100000H (* 1 MiB *)
- ELSIF fpo1[j] = 'I' THEN target.flashSize := 200000H (* 2 MiB *)
- ELSE HALT(100) (* invalid fpo1[j] *)
- END;
- target.SRAMStart := 20000000H;
- target.SRAMSize := SRAMSize;
- INC(j)
- END;
- INC(i)
- END
- END EnterSTM;
- (* Cortex-M3 *)
- PROCEDURE EnterCC1310 ((*IN*) name: TargetName; flashSize, SRAMSize: INTEGER);
- CONST
- maxExtInts = 34;
- CCFGSize = 88;
- BEGIN
- ASSERT(flashSize MOD 4 = 0, 20);
- ASSERT(SRAMSize MOD 4 = 0, 21);
- NEW(target); target.next := targets; targets := target;
- target.name := name;
- target.isNXP := FALSE;
- target.flashStart := 0;
- target.maxExtInts := maxExtInts;
- target.flashOrg := (16 + maxExtInts) * 4;
- target.flashSize := flashSize - CCFGSize;
- target.SRAMStart := 20000000H;
- target.SRAMSize := SRAMSize
- END EnterCC1310;
- (* Cortex-M3 *)
- PROCEDURE EnterLM3S ((*IN*) name: TargetName; flashSize, SRAMSize: INTEGER; maxExtInts: INTEGER);
- BEGIN
- ASSERT(flashSize MOD 4 = 0, 20);
- ASSERT(SRAMSize MOD 4 = 0, 21);
- ASSERT(maxExtInts > 0, 22);
- ASSERT(maxExtInts <= 240 (* Cortex-M4 *), 23);
- NEW(target); target.next := targets; targets := target;
- target.name := name;
- target.isNXP := FALSE;
- target.flashStart := 0;
- target.maxExtInts := maxExtInts;
- target.flashOrg := (16 + maxExtInts) * 4;
- target.flashSize := flashSize;
- target.SRAMStart := 20000000H;
- target.SRAMSize := SRAMSize
- END EnterLM3S;
- PROCEDURE EnterSAM ((*IN*) name0, fpo0: ARRAY OF CHAR; maxExtInts, flashOrg, flashSize, SRAMSize: INTEGER);
- CONST
- flashStart = 400000H;
- internalROMStart = 800000H;
- SRAMStart = 20000000H;
- VAR i, k: INTEGER;
- BEGIN
- ASSERT(maxExtInts > 0, 20);
- ASSERT(maxExtInts <= 240 (* Cortex-M4 *), 21);
- ASSERT(flashOrg MOD 80H = 0, 22);
- ASSERT(flashOrg >= (16 + maxExtInts) * 4, 23);
- ASSERT(flashSize MOD 4 = 0, 24);
- ASSERT(flashStart + flashSize <= internalROMStart, 25);
- ASSERT(SRAMSize MOD 4 = 0, 26);
- i := 0;
- WHILE i < StrLen(fpo0) DO
- NEW(target); target.next := targets; targets := target;
- target.name := name0(*$*); k := StrLen(target.name);
- target.name[k] := fpo0[i]; INC(k);
- target.name[k] := 0X;
- target.isNXP := FALSE;
- target.flashStart := flashStart;
- target.maxExtInts := maxExtInts;
- target.flashOrg := flashOrg;
- target.flashSize := flashSize;
- target.SRAMStart := SRAMStart;
- target.SRAMSize := SRAMSize;
- INC(i)
- END
- END EnterSAM;
- BEGIN Texts.OpenWriter(W); Texts.WriteString(W, "OARMv7MLinker 27.12.2021");
- Texts.WriteLn(W); Texts.Append(Oberon.Log, W.buf);
- targets := NIL;
- EnterNXP("LPC1311", 58, 2000H (* 8 KiB *), 1000H (* 4 KiB *), 32);
- EnterNXP("LPC1313", 58, 8000H (* 32 KiB *), 2000H (* 8 KiB *), 32);
- EnterNXP("LPC1342", 58, 4000H (* 16 KiB *), 1000H (* 4 KiB *), 32);
- EnterNXP("LPC1343", 58, 8000H (* 32 KiB *), 2000H (* 8 KiB *), 32);
- EnterNXP("LPC1751", 35, 8000H (* 32 KiB *), 2000H (* 8 KiB *), 32);
- EnterNXP("LPC1752", 35, 10000H (* 64 KiB *), 4000H (* 16 KiB *), 32);
- EnterNXP("LPC1754", 35, 20000H (* 128 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC1756", 35, 40000H (* 256 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC1758", 35, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1759", 35, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1763", 35, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1764", 35, 20000H (* 128 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC1765", 35, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1766", 35, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1767", 35, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1768", 35, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1769", 35, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1773", 41, 20000H (* 128 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC1774", 41, 20000H (* 128 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC1776", 41, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1777", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1778", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1785", 41, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1786", 41, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1787", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC1788", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- (* no FPU *)
- EnterNXP("LPC4072", 41, 10000H (* 64 KiB *), 4000H (* 16 KiB *), 32);
- EnterNXP("LPC4074", 41, 20000H (* 128 KiB *), 8000H (* 32 KiB *), 32);
- EnterNXP("LPC4076", 41, 40000H (* 256 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC4078", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- EnterNXP("LPC4088", 41, 80000H (* 512 KiB *), 10000H (* 64 KiB *), 32);
- (* 4 KiB of SRAM *)
- EnterSTM("STM32F100", "CR", "46", "", 61, 200H, 1000H);
- EnterSTM("STM32F101", "RT", "4", "", 60, 200H, 1000H);
- EnterSTM("STM32F102", "CR", "4", "", 60, 200H, 1000H);
- (* 6 KiB of SRAM *)
- EnterSTM("STM32F101", "CRT", "6", "", 60, 200H, 1800H);
- EnterSTM("STM32F102", "CR", "6", "", 60, 200H, 1800H);
- EnterSTM("STM32F103", "CRT", "4", "", 60, 200H, 1800H);
- (* 8 KiB of SRAM *)
- EnterSTM("STM32F100", "CRV", "8B", "", 61, 200H, 2000H);
- (* 10 KiB of SRAM *)
- EnterSTM("STM32F101", "CRTV", "8", "", 60, 200H, 2800H);
- EnterSTM("STM32F102", "CR", "8", "", 60, 200H, 2800H);
- EnterSTM("STM32F103", "CRT", "6", "", 60, 200H, 2800H);
- (* 16 KiB of SRAM *)
- EnterSTM("STM32F101", "CRTV", "B", "", 60, 200H, 4000H);
- EnterSTM("STM32F102", "CR", "B", "", 60, 200H, 4000H);
- EnterSTM("STM32F301", "CKR", "68", "", 82, 200H, 4000H);
- EnterSTM("STM32F302", "CKR", "68", "", 82, 200H, 4000H);
- EnterSTM("STM32F303", "CKR", "68", "", 82, 200H, 4000H);
- EnterSTM("STM32L151", "CR", "6", "-A", 45, 200H, 4000H);
- (* 20 KiB of SRAM *)
- EnterSTM("STM32F103", "CRTV", "8B", "", 60, 200H, 5000H);
- (* 24 KiB of SRAM *)
- EnterSTM("STM32F100", "RVZ", "C", "", 61, 200H, 6000H);
- (* 32 KiB of SRAM *)
- EnterSTM("STM32F100", "RVZ", "DE", "", 61, 200H, 8000H);
- EnterSTM("STM32F101", "RVZ", "C", "", 60, 200H, 8000H);
- EnterSTM("STM32F302", "CRV", "B", "", 85, 200H, 8000H);
- EnterSTM("STM32L151", "CRV", "8B", "-A", 45, 200H, 8000H);
- (* 40 KiB of SRAM *)
- EnterSTM("STM32F302", "CRV", "C", "", 85, 200H, 0A000H);
- EnterSTM("STM32F303", "CRV", "B", "", 85, 200H, 0A000H);
- (* 48 KiB of SRAM *)
- EnterSTM("STM32F101", "RVZ", "DE", "", 60, 200H, 0C000H);
- EnterSTM("STM32F103", "RVZ", "C", "", 60, 200H, 0C000H);
- EnterSTM("STM32F303", "CRV", "C", "", 85, 200H, 0C000H);
- (* 64 KiB of SRAM *)
- EnterSTM("STM32F103", "RVZ", "DE", "", 60, 200H, 10000H);
- EnterSTM("STM32F105", "RV", "8BC", "", 68, 200H, 10000H);
- EnterSTM("STM32F107", "RV", "BC", "", 68, 200H, 10000H);
- EnterSTM("STM32F302", "RVZ", "DE", "", 85, 200H, 10000H);
- EnterSTM("STM32F401", "CRV", "BC", "", 85, 200H, 10000H);
- (* memory hole?
- (* 48+16 KiB of SRAM *)
- EnterSTM("STM32F205", "RV", "B", "", 81, 200H, 10000H);
- *)
- (* 80 KiB of SRAM *)
- EnterSTM("STM32F101", "RVZ", "FG", "", 60, 200H, 14000H);
- EnterSTM("STM32F303", "RVZ", "DE", "", 85, 200H, 14000H);
- (* 96 KiB of SRAM *)
- EnterSTM("STM32F103", "RVZ", "FG", "", 60, 200H, 18000H);
- EnterSTM("STM32F401", "CRV", "DE", "", 85, 200H, 18000H);
- (* memory hole?
- (* 80+16 KiB of SRAM *)
- EnterSTM("STM32F205", "RVZ", "C", "", 81, 200H, 18000H);
- *)
- (* 128 KiB of SRAM *)
- EnterSTM("STM32F411", "CRV", "CE", "", 86, 200H, 20000H);
- (* 112+16 KiB of SRAM *)
- EnterSTM("STM32F205", "RVZ", "EFG", "", 81, 200H, 20000H);
- EnterSTM("STM32F207", "IVZ", "CEFG", "", 81, 200H, 20000H);
- EnterSTM("STM32F215", "RVZ", "EG", "", 81, 200H, 20000H);
- EnterSTM("STM32F217", "IVZ", "EG", "", 81, 200H, 20000H);
- EnterSTM("STM32F405", "O", "E", "", 82, 200H, 20000H);
- EnterSTM("STM32F405", "ORVZ", "G", "", 82, 200H, 20000H);
- EnterSTM("STM32F407", "IVZ", "EG", "", 82, 200H, 20000H);
- EnterSTM("STM32F415", "ORVZ", "G", "", 82, 200H, 20000H);
- EnterSTM("STM32F417", "IVZ", "EG", "", 82, 200H, 20000H);
- EnterSTM("STM32F446", "MRVZ", "CE", "", 97, 200H, 20000H);
- (* 112+16+64 KiB of SRAM *)
- EnterSTM("STM32F427", "IVZ", "GI", "", 91, 200H, 30000H);
- EnterSTM("STM32F429", "BINVZ", "EGI", "", 91, 200H, 30000H);
- EnterSTM("STM32F437", "IVZ", "GI", "", 91, 200H, 30000H);
- EnterSTM("STM32F439", "BINVZ", "GI", "", 91, 200H, 30000H);
- (* 64 KiB (DTCM) + 240 KiB (SRAM1) + 16 KiB (SRAM2) *)
- EnterSTM("STM32F756", "BINVZ", "EG", "",
- 98, (16 + 240) * 4 (* FIXME *), 50000H);
- (* 128 KiB (DTCM) *)
- EnterSTM("STM32H723", "VZ", "EG", "",
- 163, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H725", "AIRVZ", "EG", "",
- 163, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H730", "AIVZ", "B", "",
- 163, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H733", "VZ", "G", "",
- 163, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H735", "AIRVZ", "G", "",
- 163, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H742", "ABIVXZ", "GI", "",
- 150, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H743", "ABIVXZ", "GI", "",
- 150, (16 + 240) * 4, 20000H);
- (*
- EnterSTM("STM32H745", "BIXZ", "GI", "",
- 150, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H747", "ABIX", "GI", "",
- 150, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H747", "Z", "I", "",
- 150, (16 + 240) * 4, 20000H);
- *)
- EnterSTM("STM32H750", "IVXZ", "B", "",
- 150, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H753", "ABIVXZ", "I", "",
- 150, (16 + 240) * 4, 20000H);
- (*
- EnterSTM("STM32H755", "BIXZ", "I", "",
- 150, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H757", "ABIXZ", "I", "",
- 150, (16 + 240) * 4, 20000H);
- *)
- EnterSTM("STM32H7A3", "AILNRVZ", "IG", "",
- 155, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H7B3", "AILNRVZ", "I", "",
- 155, (16 + 240) * 4, 20000H);
- EnterSTM("STM32H7B0", "AIRVZ", "B", "",
- 155, (16 + 240) * 4, 20000H);
- EnterCC1310("CC1310F32", 8000H (* 32 KiB *), 4000H (* 16 KiB *));
- EnterCC1310("CC1310F64", 10000H (* 64 KiB *), 4000H (* 16 KiB *));
- EnterCC1310("CC1310F128", 20000H (* 128 KiB *), 5000H (* 20 KiB *));
- EnterLM3S("LM3S811", 10000H (* 64 KiB *), 2000H (* 8 KiB *), 26);
- EnterLM3S("LM3S6965", 40000H (* 256 KiB *), 10000H (* 64 KiB *), 38);
- EnterSAM("SAM3S1", "ABC", 35, 200H,
- 10000H (* 64 KiB *), 4000H (* 16 KiB *));
- EnterSAM("SAM3S2", "ABC", 35, 200H,
- 20000H (* 128 KiB *), 8000H (* 32 KiB *));
- EnterSAM("SAM3S4", "ABC", 35, 200H,
- 40000H (* 256 KiB *), 0C000H (* 48 KiB *))
- END O7ARMv7MLinker.
|