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 -------------------------------------------------------------------------*/
26 int summary(struct area * areap)
28 #define EQ(A,B) !as_strcmpi((A),(B))
30 #define REPORT_ERROR(A, H) \
32 fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
33 fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
37 #define REPORT_WARNING(A, H) \
39 fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
40 fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
45 unsigned int Total_Last=0, k;
50 /*Artifacts used for printing*/
51 char start[15], end[15], size[15], max[15];
52 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
53 char line[]="---------------------";
64 unsigned int dram[0x100];
66 {0, 8, 8, "REG_BANK_0", 0x0001},
67 {0x8, 8, 8, "REG_BANK_1", 0x0002},
68 {0x10, 8, 8, "REG_BANK_2", 0x0004},
69 {0x18, 8, 8, "REG_BANK_3", 0x0008},
70 {0x20, 0, 16, "BSEG_BYTES", 0x0010},
71 {0, 0, 128, "UNUSED", 0x0000},
72 {0x7f, 0, 128, "DATA", 0x0020},
73 {0, 0, 128, "TOTAL:", 0x0000}
76 _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080};
77 _Mem Stack={0xff, 0, 1, "STACK", 0x0000};
78 _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
79 _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
81 if(stacksize==0) stacksize=MIN_STACK;
83 if(rflag) /*For the DS390*/
85 XRam.Max=0x1000000; /*24 bits*/
91 if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
99 else if(iram_size<0x80)
101 Ram[5].Max=iram_size;
102 Ram[6].Max=iram_size;
103 Ram[7].Max=iram_size;
111 IRam.Max=iram_size-0x80;
114 for(j=0; j<(int)iram_size; j++) dram[j]=0;
115 for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
117 /* Open Memory Summary File*/
118 of = afile(linkp->f_idp, "mem", 1);
127 /**/ if (EQ(xp->a_id, "REG_BANK_0"))
129 Ram[0].Size=xp->a_size;
131 else if (EQ(xp->a_id, "REG_BANK_1"))
133 Ram[1].Size=xp->a_size;
135 else if (EQ(xp->a_id, "REG_BANK_2"))
137 Ram[2].Size=xp->a_size;
139 else if (EQ(xp->a_id, "REG_BANK_3"))
141 Ram[3].Size=xp->a_size;
143 else if (EQ(xp->a_id, "BSEG_BYTES"))
145 Ram[4].Size+=xp->a_size;
147 else if (EQ(xp->a_id, "BIT_BANK"))
149 Ram[4].Size+=xp->a_size;
152 else if(xp->a_flag & A_CODE)
156 Rom.Size+=xp->a_size;
157 if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
161 else if (EQ(xp->a_id, "SSEG"))
163 Stack.Size+=xp->a_size;
164 if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
167 else if(xp->a_flag & A_XDATA)
171 XRam.Size+=xp->a_size;
172 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;
182 /*If is not a register bank, bit, stack, or idata, then it should be data*/
183 else if((xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0)
187 Ram[6].Size+=xp->a_size;
188 if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
196 for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
197 dram[k]|=Ram[j].flag; /*Mark as used*/
199 for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
200 dram[k]|=IRam.flag; /*Mark as used*/
202 /*Compute the amount of unused memory in direct data Ram. This is the
203 gap between the last register bank or bit segment and the data segment.*/
204 for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
206 Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
208 /*Compute the data Ram totals*/
211 if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
212 Ram[7].Size+=Ram[j].Size;
214 Total_Last=Ram[6].Size+Ram[6].Start-1;
216 /*Report the Ram totals*/
217 fprintf(of, "Direct Internal RAM:\n");
218 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
222 if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
223 if((j!=5) || (Ram[j].Size>0))
225 sprintf(start, "0x%02lx", Ram[j].Start);
227 end[0]=0;/*Empty string*/
229 sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
230 sprintf(size, "%5lu", Ram[j].Size);
231 sprintf(max, "%5lu", Ram[j].Max);
232 fprintf(of, format, Ram[j].Name, start, end, size, max);
236 for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
238 if(dram[k]!=Ram[6].flag)
240 sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
241 REPORT_ERROR(buff, 1);
246 if(Ram[4].Size>Ram[4].Max)
248 k=Ram[4].Size-Ram[4].Max;
249 sprintf(buff, "Insufficient bit addressable memory. "
250 "%d byte%s short.\n", k, (k==1)?"":"s");
251 REPORT_ERROR(buff, 1);
256 sprintf(buff, "%ld bytes in data memory wasted. "
257 "SDCC link could use: --data-loc 0x%02lx\n",
258 Ram[5].Size, Ram[6].Start-Ram[5].Size);
259 REPORT_WARNING(buff, 1);
262 if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
264 k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
265 sprintf(buff, "Insufficient space in data memory. "
266 "%d byte%s short.\n", k, (k==1)?"":"s");
267 REPORT_ERROR(buff, 1);
270 /*Report the position of the beginning of the stack*/
271 fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
272 rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
274 /*Check that the stack pointer is landing in a safe place:*/
275 if( (dram[Stack.Start] & 0x8000) == 0x8000 )
278 sprintf(buff, "Stack set to unavailable memory.\n");
279 REPORT_ERROR(buff, 1);
281 else if(dram[Stack.Start])
284 sprintf(buff, "Stack overlaps area ");
285 REPORT_ERROR(buff, 1);
288 if(dram[Stack.Start]&Ram[j].flag)
290 sprintf(buff, "'%s'\n", Ram[j].Name);
294 if(dram[Stack.Start]&IRam.flag)
296 sprintf(buff, "'%s'\n", IRam.Name);
298 REPORT_ERROR(buff, 0);
302 for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
303 fprintf(of, " with %d bytes available\n", k);
304 if ((int)k<stacksize)
306 sprintf(buff, "Only %d byte%s available for stack.\n",
308 REPORT_WARNING(buff, 1);
312 fprintf(of, "\nOther memory:\n");
313 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
314 fprintf(of, format, line, line, line, line, line);
316 /*Report IRam totals:*/
319 start[0]=0;/*Empty string*/
320 end[0]=0;/*Empty string*/
324 sprintf(start, "0x%02lx", IRam.Start);
325 sprintf(end, "0x%02lx", IRam.Size+IRam.Start-1);
327 sprintf(size, "%5lu", IRam.Size);
328 sprintf(max, "%5lu", IRam.Max);
329 fprintf(of, format, IRam.Name, start, end, size, max);
331 /*Report XRam totals:*/
334 start[0]=0;/*Empty string*/
335 end[0]=0;/*Empty string*/
339 sprintf(start, "0x%04lx", XRam.Start);
340 sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
342 sprintf(size, "%5lu", XRam.Size);
343 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
344 fprintf(of, format, XRam.Name, start, end, size, max);
346 /*Report Rom/Flash totals:*/
349 start[0]=0;/*Empty string*/
350 end[0]=0;/*Empty string*/
354 sprintf(start, "0x%04lx", Rom.Start);
355 sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
357 sprintf(size, "%5lu", Rom.Size);
358 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
359 fprintf(of, format, Rom.Name, start, end, size, max);
361 /*Report any excess:*/
362 if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
364 sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
365 REPORT_ERROR(buff, 1);
367 if( ((XRam.Start+XRam.Size)>XRam.Max) ||
368 (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
370 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
371 REPORT_ERROR(buff, 1);
373 if( ((Rom.Start+Rom.Size)>Rom.Max) ||
374 (((int)Rom.Size>code_size)&&(code_size>=0)) )
376 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
377 REPORT_ERROR(buff, 1);
384 extern char idatamap[]; //0:not used, 1:used
387 int summary2(struct area * areap)
389 #define EQ(A,B) !as_strcmpi((A),(B))
394 unsigned long int Stack_Start=0, Stack_Size;
397 struct area * xstack_xp = NULL;
400 /*Artifacts used for printing*/
401 char start[15], end[15], size[15], max[15];
402 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
403 char line[]="---------------------";
415 _Mem Stack={0xff, 0, 0, 1, "STACK", 0x0000};
416 _Mem Paged={0xff, 0, 0, 256, "PAGED EXT. RAM", A_PAG};
417 _Mem XRam= {0xffff, 0, 0, 65536, "EXTERNAL RAM", 0x0100};
418 _Mem Rom= {0xffff, 0, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
420 if(rflag) /*For the DS390*/
422 XRam.Max=0x1000000; /*24 bits*/
428 /* Open Memory Summary File*/
429 of = afile(linkp->f_idp, "mem", 1);
438 if (xp->a_flag & A_CODE)
442 Rom.Size += xp->a_size;
443 if(xp->a_addr < Rom.Start)
444 Rom.Start = xp->a_addr;
445 if(xp->a_addr + xp->a_size > Rom.End)
446 Rom.End = xp->a_addr + xp->a_size;
450 else if (EQ(xp->a_id, "SSEG"))
452 Stack.Size += xp->a_size;
453 if(xp->a_addr < Stack.Start)
454 Stack.Start = xp->a_addr;
455 if(xp->a_addr + xp->a_size > Stack.End)
456 Stack.End = xp->a_addr + xp->a_size;
459 else if (EQ(xp->a_id, "PSEG"))
461 Paged.Size += xp->a_size;
462 if(xp->a_addr < Paged.Start)
463 Paged.Start = xp->a_addr;
464 if(xp->a_addr + xp->a_size > Paged.End)
465 Paged.End = xp->a_addr + xp->a_size;
468 else if (EQ(xp->a_id, "XSTK"))
471 Paged.Size += xp->a_size;
472 if(xp->a_addr < Paged.Start)
473 Paged.Start = xp->a_addr;
474 if(xp->a_addr + xp->a_size > Paged.End)
475 Paged.End = xp->a_addr + xp->a_size;
478 else if (xp->a_flag & A_XDATA)
482 XRam.Size += xp->a_size;
483 if(xp->a_addr < XRam.Start)
484 XRam.Start = xp->a_addr;
485 if(xp->a_addr + xp->a_size > XRam.End)
486 XRam.End = xp->a_addr + xp->a_size;
493 /*Report the Ram totals*/
494 fprintf(of, "Internal RAM layout:\n");
495 fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F");
498 if(j%16==0) fprintf(of, "\n0x%02x:|", j);
499 fprintf(of, "%c|", idatamap[j]);
501 fprintf(of, "\n0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute\n");
512 for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++)
514 if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_Size++;
523 fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
524 " in internal RAM for area %s.",
525 xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
531 /*Report the position of the begining of the stack*/
533 fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
534 rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_Size);
536 fprintf(of, "\nI don't have a clue where the stack ended up! Sorry...");
538 /*Report about xstack*/
541 Stack_Start = xstack_xp->a_addr;
542 Stack_Size = xstack_xp->a_size;
543 fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.",
544 Stack_Start, Stack_Size);
547 fprintf(of, "\n\nOther memory:\n");
548 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
549 fprintf(of, format, line, line, line, line, line);
551 /*Report Paged XRam totals:*/
554 start[0]=0;/*Empty string*/
555 end[0]=0;/*Empty string*/
559 sprintf(start, "0x%04lx", Paged.Start);
560 sprintf(end, "0x%04lx", Paged.End-1);
562 sprintf(size, "%5lu", Paged.Size);
563 sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256);
564 fprintf(of, format, Paged.Name, start, end, size, max);
566 /*Report XRam totals:*/
569 start[0]=0;/*Empty string*/
570 end[0]=0;/*Empty string*/
574 sprintf(start, "0x%04lx", XRam.Start);
575 sprintf(end, "0x%04lx", XRam.End-1);
577 sprintf(size, "%5lu", XRam.Size);
578 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
579 fprintf(of, format, XRam.Name, start, end, size, max);
581 /*Report Rom/Flash totals:*/
584 start[0]=0;/*Empty string*/
585 end[0]=0;/*Empty string*/
589 sprintf(start, "0x%04lx", Rom.Start);
590 sprintf(end, "0x%04lx", Rom.End-1);
592 sprintf(size, "%5lu", Rom.Size);
593 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
594 fprintf(of, format, Rom.Name, start, end, size, max);
596 /*Report any excess:*/
597 if( ((XRam.End) > XRam.Max) ||
598 (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
600 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
601 REPORT_ERROR(buff, 1);
603 if( ((Rom.End) > Rom.Max) ||
604 (((int)Rom.Size>code_size)&&(code_size>=0)) )
606 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
607 REPORT_ERROR(buff, 1);