1 /*-------------------------------------------------------------------------
2 lkmem.c - Create a memory summary file with extension .mem
4 Written By - Jesus Calvino-Fraga, jesusc@ieee.org (2002)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 -------------------------------------------------------------------------*/
27 int summary(struct area * areap)
29 #define EQ(A,B) !as_strcmpi((A),(B))
31 #define REPORT_ERROR(A, H) \
33 fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
34 fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
38 #define REPORT_WARNING(A, H) \
40 fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
41 fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
46 unsigned int Total_Last=0, k;
51 /*Artifacts used for printing*/
52 char start[15], end[15], size[15], max[15];
53 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
54 char line[]="---------------------";
65 unsigned int dram[0x100];
67 {0, 8, 8, "REG_BANK_0", 0x0001},
68 {0x8, 8, 8, "REG_BANK_1", 0x0002},
69 {0x10, 8, 8, "REG_BANK_2", 0x0004},
70 {0x18, 8, 8, "REG_BANK_3", 0x0008},
71 {0x20, 0, 16, "BSEG_BYTES", 0x0010},
72 {0, 0, 128, "UNUSED", 0x0000},
73 {0x7f, 0, 128, "DATA", 0x0020},
74 {0, 0, 128, "TOTAL:", 0x0000}
77 _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080};
78 _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
79 _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
80 _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
82 if(stacksize==0) stacksize=MIN_STACK;
84 if(rflag) /*For the DS390*/
86 XRam.Max=0x1000000; /*24 bits*/
92 if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
100 else if(iram_size<0x80)
102 Ram[5].Max=iram_size;
103 Ram[6].Max=iram_size;
104 Ram[7].Max=iram_size;
112 IRam.Max=iram_size-0x80;
115 for(j=0; j<(int)iram_size; j++) dram[j]=0;
116 for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
118 /* Open Memory Summary File*/
119 of = afile(linkp->f_idp, "mem", 1);
128 /**/ if (EQ(xp->a_id, "REG_BANK_0"))
130 Ram[0].Size=xp->a_size;
132 else if (EQ(xp->a_id, "REG_BANK_1"))
134 Ram[1].Size=xp->a_size;
136 else if (EQ(xp->a_id, "REG_BANK_2"))
138 Ram[2].Size=xp->a_size;
140 else if (EQ(xp->a_id, "REG_BANK_3"))
142 Ram[3].Size=xp->a_size;
144 else if (EQ(xp->a_id, "BSEG_BYTES"))
146 Ram[4].Size=xp->a_size;
148 else if ( EQ(xp->a_id, "DSEG") || EQ(xp->a_id, "OSEG") )
150 Ram[6].Size+=xp->a_size;
151 if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
154 else if( EQ(xp->a_id, "CSEG") || EQ(xp->a_id, "GSINIT") ||
155 EQ(xp->a_id, "GSINIT0") || EQ(xp->a_id, "GSINIT1") ||
156 EQ(xp->a_id, "GSINIT2") || EQ(xp->a_id, "GSINIT3") ||
157 EQ(xp->a_id, "GSINIT4") || EQ(xp->a_id, "GSINIT5") ||
158 EQ(xp->a_id, "GSFINAL") || EQ(xp->a_id, "HOME") )
160 Rom.Size+=xp->a_size;
161 if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
164 else if (EQ(xp->a_id, "SSEG"))
166 Stack.Size+=xp->a_size;
167 if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
170 else if (EQ(xp->a_id, "XSEG") || EQ(xp->a_id, "XISEG"))
172 XRam.Size+=xp->a_size;
173 if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
176 else if (EQ(xp->a_id, "ISEG"))
178 IRam.Size+=xp->a_size;
179 if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
185 for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
186 dram[k]|=Ram[j].flag; /*Mark as used*/
188 for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
189 dram[k]|=IRam.flag; /*Mark as used*/
191 /*Compute the amount of unused memory in direct data Ram. This is the
192 gap between the last register bank or bit segment and the data segment.*/
193 for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
195 Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
197 /*Compute the data Ram totals*/
200 if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
201 Ram[7].Size+=Ram[j].Size;
203 Total_Last=Ram[6].Size+Ram[6].Start-1;
205 /*Report the Ram totals*/
206 fprintf(of, "Direct Internal RAM:\n");
207 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
211 if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
212 if((j!=5) || (Ram[j].Size>0))
214 sprintf(start, "0x%02lx", Ram[j].Start);
216 end[0]=0;/*Empty string*/
218 sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
219 sprintf(size, "%5lu", Ram[j].Size);
220 sprintf(max, "%5lu", Ram[j].Max);
221 fprintf(of, format, Ram[j].Name, start, end, size, max);
225 for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
227 if(dram[k]!=Ram[6].flag)
229 sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
230 REPORT_ERROR(buff, 1);
235 if(Ram[4].Size>Ram[4].Max)
237 k=Ram[4].Size-Ram[4].Max;
238 sprintf(buff, "Insufficient bit addressable memory. "
239 "%d byte%s short.\n", k, (k==1)?"":"s");
240 REPORT_ERROR(buff, 1);
245 sprintf(buff, "%ld bytes in data memory wasted. "
246 "SDCC link could use: --data-loc 0x%02lx\n",
247 Ram[5].Size, Ram[6].Start-Ram[5].Size);
248 REPORT_WARNING(buff, 1);
251 if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
253 k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
254 sprintf(buff, "Insufficient space in data memory. "
255 "%d byte%s short.\n", k, (k==1)?"":"s");
256 REPORT_ERROR(buff, 1);
259 /*Report the position of the begining of the stack*/
260 fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
261 rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
263 /*Check that the stack pointer is landing in a safe place:*/
264 if( (dram[Stack.Start] & 0x8000) == 0x8000 )
267 sprintf(buff, "Stack set to unavailable memory.\n");
268 REPORT_ERROR(buff, 1);
270 else if(dram[Stack.Start])
273 sprintf(buff, "Stack overlaps area ");
274 REPORT_ERROR(buff, 1);
277 if(dram[Stack.Start]&Ram[j].flag)
279 sprintf(buff, "'%s'\n", Ram[j].Name);
283 if(dram[Stack.Start]&IRam.flag)
285 sprintf(buff, "'%s'\n", IRam.Name);
287 REPORT_ERROR(buff, 0);
291 for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
292 fprintf(of, " with %d bytes available\n", k);
293 if ((int)k<stacksize)
295 sprintf(buff, "Only %d byte%s available for stack.\n",
297 REPORT_WARNING(buff, 1);
301 fprintf(of, "\nOther memory:\n");
302 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
303 fprintf(of, format, line, line, line, line, line);
305 /*Report IRam totals:*/
306 sprintf(start, "0x%02lx", IRam.Start);
308 end[0]=0;/*Empty string*/
310 sprintf(end, "0x%02lx", IRam.Size+IRam.Start-1);
311 sprintf(size, "%5lu", IRam.Size);
312 sprintf(max, "%5lu", IRam.Max);
313 fprintf(of, format, IRam.Name, start, end, size, max);
315 /*Report XRam totals:*/
316 sprintf(start, "0x%04lx", XRam.Start);
318 end[0]=0;/*Empty string*/
320 sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
321 sprintf(size, "%5lu", XRam.Size);
322 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
323 fprintf(of, format, XRam.Name, start, end, size, max);
325 /*Report Rom/Flash totals:*/
326 sprintf(start, "0x%04lx", Rom.Start);
328 end[0]=0;/*Empty string*/
330 sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
331 sprintf(size, "%5lu", Rom.Size);
332 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
333 fprintf(of, format, Rom.Name, start, end, size, max);
335 /*Report any excess:*/
336 if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
338 sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
339 REPORT_ERROR(buff, 1);
341 if( ((XRam.Start+XRam.Size)>XRam.Max) ||
342 (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
344 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
345 REPORT_ERROR(buff, 1);
347 if( ((Rom.Start+Rom.Size)>Rom.Max) ||
348 (((int)Rom.Size>code_size)&&(code_size>=0)) )
350 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
351 REPORT_ERROR(buff, 1);
358 extern char idatamap[]; //0:not used, 1:used
361 int summary2(struct area * areap)
363 #define EQ(A,B) !as_strcmpi((A),(B))
367 long int Stack_Start=0, Stack_size;
372 /*Artifacts used for printing*/
373 char start[15], end[15], size[15], max[15];
374 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
375 char line[]="---------------------";
386 _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
387 _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
388 _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
390 if(rflag) /*For the DS390*/
392 XRam.Max=0x1000000; /*24 bits*/
398 /* Open Memory Summary File*/
399 of = afile(linkp->f_idp, "mem", 1);
408 if( EQ(xp->a_id, "CSEG") || EQ(xp->a_id, "GSINIT") ||
409 EQ(xp->a_id, "GSINIT0") || EQ(xp->a_id, "GSINIT1") ||
410 EQ(xp->a_id, "GSINIT2") || EQ(xp->a_id, "GSINIT3") ||
411 EQ(xp->a_id, "GSINIT4") || EQ(xp->a_id, "GSINIT5") ||
412 EQ(xp->a_id, "GSFINAL") || EQ(xp->a_id, "HOME") )
414 Rom.Size+=xp->a_size;
415 if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
418 else if (EQ(xp->a_id, "SSEG"))
420 Stack.Size+=xp->a_size;
421 if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
424 else if (EQ(xp->a_id, "XSEG") || EQ(xp->a_id, "XISEG"))
426 XRam.Size+=xp->a_size;
427 if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
433 /*Report the Ram totals*/
434 fprintf(of, "Internal RAM layout:\n");
435 fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F");
438 if(j%16==0) fprintf(of, "\n0x%02x:|", j);
439 fprintf(of, "%c|", idatamap[j]);
441 fprintf(of, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
452 for(j=Stack_Start, Stack_size=0; j<256; j++)
454 if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_size++;
463 fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
464 " in internal RAM for area %s.",
465 xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
471 /*Report the position of the begining of the stack*/
473 fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
474 rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_size);
476 fprintf(of, "\nI don't have a clue where the stack ended up! Sorry...");
478 fprintf(of, "\n\nOther memory:\n");
479 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
480 fprintf(of, format, line, line, line, line, line);
482 /*Report XRam totals:*/
483 sprintf(start, "0x%04lx", XRam.Start);
485 end[0]=0;/*Empty string*/
487 sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
488 sprintf(size, "%5lu", XRam.Size);
489 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
490 fprintf(of, format, XRam.Name, start, end, size, max);
492 /*Report Rom/Flash totals:*/
493 sprintf(start, "0x%04lx", Rom.Start);
495 end[0]=0;/*Empty string*/
497 sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
498 sprintf(size, "%5lu", Rom.Size);
499 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
500 fprintf(of, format, Rom.Name, start, end, size, max);
502 /*Report any excess:*/
503 if( ((XRam.Start+XRam.Size)>XRam.Max) ||
504 (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
506 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
507 REPORT_ERROR(buff, 1);
509 if( ((Rom.Start+Rom.Size)>Rom.Max) ||
510 (((int)Rom.Size>code_size)&&(code_size>=0)) )
512 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
513 REPORT_ERROR(buff, 1);