OpenCores
URL https://opencores.org/ocsvn/mips789/mips789/trunk

Subversion Repositories mips789

[/] [mips789/] [tags/] [arelease/] [CTool/] [convert_sp.c] - Blame information for rev 51

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 35 mcupro
 
2 10 mcupro
/* convert.c by Steve Rhoads 4/26/01 */
3
/* Now uses the ELF format (get gccmips_elf.zip) */
4
/* set $gp and zero .sbss and .bss */
5
/* Reads test.axf and creates code.txt */
6
/* modified by Liwei 2007-8-29 */
7
#include <stdio.h>
8
#include <stdlib.h>
9
#include <string.h>
10
#define BUF_SIZE (1024*1024*4)
11
/*Assumes running on PC little endian*/
12
#ifndef USE_BIG_ENDIAN 
13
#define ntohl(A) (((A)>>24)|(((A)&0x00ff0000)>>8)|(((A)&0xff00)<<8)|((A)<<24))
14
#define ntohs(A) (unsigned short)((((A)&0xff00)>>8)|((A)<<8))
15
#else 
16
#define ntohl(A) A 
17
#define ntohs(A) A 
18
#endif 
19
 
20
#define EI_NIDENT 16 
21
#define SHT_PROGBITS 1 
22
#define SHT_STRTAB 3 
23
#define SHT_NOBITS 8 
24
 
25
typedef struct
26
{
27
    unsigned char e_ident[EI_NIDENT];
28
    unsigned short e_e_type ;
29
    unsigned short e_machine ;
30
    unsigned long e_version ;
31
    unsigned long e_entry ;
32
    unsigned long e_phoff ;
33
    unsigned long e_shoff ;
34
    unsigned long e_flags ;
35
    unsigned short e_ehsize ;
36
    unsigned short e_phentsize ;
37
    unsigned short e_phnum ;
38
    unsigned short e_shentsize ;
39
    unsigned short e_shnum ;
40
    unsigned short e_shstrndx ;
41
}
42
ElfHeader ;
43
 
44
typedef struct
45
{
46
    unsigned long p_type ;
47
    unsigned long p_offset ;
48
    unsigned long p_vaddr ;
49
    unsigned long p_paddr ;
50
    unsigned long p_filesz ;
51
    unsigned long p_memsz ;
52
    unsigned long p_flags ;
53
    unsigned long p_align ;
54
}
55
Elf32_Phdr ;
56
 
57
typedef struct
58
{
59
    unsigned long sh_name ;
60
    unsigned long sh_type ;
61
    unsigned long sh_flags ;
62
    unsigned long sh_addr ;
63
    unsigned long sh_offset ;
64
    unsigned long sh_size ;
65
    unsigned long sh_link ;
66
    unsigned long sh_info ;
67
    unsigned long sh_addralign ;
68
    unsigned long sh_entsize ;
69
}
70
Elf32_Shdr ;
71
 
72
typedef struct
73
{
74
    unsigned long ri_gprmask ;
75
    unsigned long ri_cprmask[4];
76
    unsigned long ri_gp_value ;
77
}
78
ELF_RegInfo ;
79
 
80
#define PT_MIPS_REGINFO 0x70000000 
81
#define SHT_MIPS_REGINFO 0x70000006 
82
 
83
void set_low(unsigned char*ptr,unsigned long address,unsigned long value)
84
{
85
    unsigned long opcode ;
86
    opcode=*(unsigned long*)(ptr+address);
87
    opcode=ntohl(opcode);
88
    opcode=(opcode&0xffff0000)|(value&0xffff);
89
    opcode=ntohl(opcode);
90
    *(unsigned long*)(ptr+address)=opcode ;
91
}
92
 
93
/*the two functions listed between are added by Liwei 2007-8-29*/
94
char HEX[]="0123456789ABCDEF" ;
95
char hex[]="0123456789abcdef" ;
96
unsigned char hex2byte(char hex_char)
97
{
98
    unsigned char i ;
99
    for(i=0;i<16;++i)if(HEX[i]==hex_char)return i ;
100
    for(i=0;i<16;++i)if(hex[i]==hex_char)return i ;
101
    return 0 ;
102
}
103
unsigned int par2u32(char*par)
104
{
105
    unsigned int i,ret=0 ;
106
    if(par==NULL)return ;
107
    if((0==strncmp(par,"0x",2))||(0==strncmp(par,"0X",2)))
108
    for(i=2;;++i)
109
    {
110
        if(par[i]=='\0')return ret ;
111 35 mcupro
        if(par[i]==' ')return ret ;
112 10 mcupro
        ret=ret*16+hex2byte(par[i]);
113
    }
114
    else
115
    for(i=0;;++i)
116
    {
117
        if(par[i]=='\0')return ret ;
118 35 mcupro
        if(par[i]==' ')return ret ;
119 10 mcupro
        ret=ret*10+hex2byte(par[i]);
120
    }
121
    return 0 ;
122
}
123
/****************************/
124
 
125
int main(int argc,char*argv[])
126
{
127
    FILE*infile,*outfile,*txtfile ;
128
    unsigned char*buf,*code ;
129
    long size,stack_pointer ;
130
    long stack_limit=0 ;
131
    unsigned long length,d,i,gp_ptr=0,gp_ptr_backup=0 ;
132
    unsigned long bss_start=0,bss_end=0 ;
133
 
134
    ElfHeader*elfHeader ;
135
    Elf32_Phdr*elfProgram ;
136
    ELF_RegInfo*elfRegInfo ;
137
    Elf32_Shdr*elfSection ;
138
    (void)argc ;
139
    (void)argv ;
140
    //    printf(">%s<=>%d<\n",argv[1],par2u32((char*)argv[1]));//Liwei 2007-8.29
141
    //   printf(">%s<=>%d<\n",argv[2],par2u32((char*)argv[2]));//Liwei 2007-8.29
142
    // printf("argc = %d\n",argc);
143
    if(argc>=3)
144
    stack_limit=((par2u32((char*)argv[1])-par2u32((char*)argv[2])));
145
    //alig 4
146
    /* added by Liwei  2007_8_29 */
147
    /*usage example :
148
                       convert_sp 0x800 0xf0
149
                       the sp_pointer is limited and set as (0x800 - 0xf0)
150
                       0x800 is your instructions space lenth while 0xf0 is your stack lenth
151
                       but make sure your instructions space is big enough...
152
                       comment by Liwei
153
                       */
154
    printf("test.axf -> code.txt & test.bin\n");
155
    infile=fopen("test.axf","rb");
156
    if(infile==NULL)
157
    {
158
        printf("Can't open test.axf");
159
        return 0 ;
160
    }
161
    buf=(unsigned char*)malloc(BUF_SIZE);
162
    size=(int)fread(buf,1,BUF_SIZE,infile);
163
    fclose(infile);
164
    code=(unsigned char*)malloc(BUF_SIZE);
165
    memset(code,0,BUF_SIZE);
166
 
167
    elfHeader=(ElfHeader*)buf ;
168
    if(strncmp((char*)elfHeader->e_ident+1,"ELF",3))
169
    {
170
        printf("Error:  Not an ELF file!\n");
171
        printf("Use the gccmips_elf.zip from opencores/projects/plasma!\n");
172
        return-1 ;
173
    }
174
 
175
    elfHeader->e_entry=ntohl(elfHeader->e_entry);
176
    elfHeader->e_phoff=ntohl(elfHeader->e_phoff);
177
    elfHeader->e_shoff=ntohl(elfHeader->e_shoff);
178
    elfHeader->e_flags=ntohl(elfHeader->e_flags);
179
    elfHeader->e_phentsize=ntohs(elfHeader->e_phentsize);
180
    elfHeader->e_phnum=ntohs(elfHeader->e_phnum);
181
    elfHeader->e_shentsize=ntohs(elfHeader->e_shentsize);
182
    elfHeader->e_shnum=ntohs(elfHeader->e_shnum);
183
    printf("Entry=0x%x ",elfHeader->e_entry);
184
    length=0 ;
185
 
186
    for(i=0;i<elfHeader->e_phnum;++i)
187
    {
188
        elfProgram=(Elf32_Phdr*)(buf+elfHeader->e_phoff+
189
        elfHeader->e_phentsize*i);
190
        elfProgram->p_type=ntohl(elfProgram->p_type);
191
        elfProgram->p_offset=ntohl(elfProgram->p_offset);
192
        elfProgram->p_vaddr=ntohl(elfProgram->p_vaddr);
193
        elfProgram->p_filesz=ntohl(elfProgram->p_filesz);
194
        elfProgram->p_memsz=ntohl(elfProgram->p_memsz);
195
        elfProgram->p_flags=ntohl(elfProgram->p_flags);
196
 
197
        elfProgram->p_vaddr-=elfHeader->e_entry ;
198
 
199
        if(elfProgram->p_type==PT_MIPS_REGINFO)
200
        {
201
            elfRegInfo=(ELF_RegInfo*)(buf+elfProgram->p_offset);
202
            gp_ptr=ntohl(elfRegInfo->ri_gp_value);
203
        }
204
        if(elfProgram->p_vaddr<BUF_SIZE)
205
        {
206
            /* printf("[0x%x,0x%x,0x%x,0x%x,0x%x]\n", elfProgram->p_vaddr, */
207
            /*    elfProgram->p_offset, elfProgram->p_filesz, elfProgram->p_memsz, */
208
            /*    elfProgram->p_flags); */
209
            memcpy(code+elfProgram->p_vaddr,buf+elfProgram->p_offset,
210
            elfProgram->p_filesz);
211
            length=elfProgram->p_vaddr+elfProgram->p_filesz ;
212
            /* printf("length = %d 0x%x\n", length, length); */
213
        }
214
    }
215
 
216
    for(i=0;i<elfHeader->e_shnum;++i)
217
    {
218
        elfSection=(Elf32_Shdr*)(buf+elfHeader->e_shoff+
219
        elfHeader->e_shentsize*i);
220
        elfSection->sh_name=ntohl(elfSection->sh_name);
221
        elfSection->sh_type=ntohl(elfSection->sh_type);
222
        elfSection->sh_addr=ntohl(elfSection->sh_addr);
223
        elfSection->sh_offset=ntohl(elfSection->sh_offset);
224
        elfSection->sh_size=ntohl(elfSection->sh_size);
225
 
226
        if(elfSection->sh_type==SHT_MIPS_REGINFO)
227
        {
228
            elfRegInfo=(ELF_RegInfo*)(buf+elfSection->sh_offset);
229
            gp_ptr=ntohl(elfRegInfo->ri_gp_value);
230
        }
231
        if(elfSection->sh_type==SHT_PROGBITS)
232
        {
233
            /* printf("elfSection->sh_addr=0x%x\n", elfSection->sh_addr); */
234
            if(elfSection->sh_addr>gp_ptr_backup)
235
            gp_ptr_backup=elfSection->sh_addr ;
236
        }
237
        if(elfSection->sh_type==SHT_NOBITS)
238
        {
239
            if(bss_start==0)
240
            {
241
                bss_start=elfSection->sh_addr ;
242
            }
243
            bss_end=elfSection->sh_addr+elfSection->sh_size ;
244
        }
245
    }
246
 
247
    if(length>bss_start-elfHeader->e_entry)
248
    {
249
        length=bss_start-elfHeader->e_entry ;
250
    }
251
    if(bss_start==length)
252
    {
253
        bss_start=length ;
254
        bss_end=length+4 ;
255
    }
256
    if(gp_ptr==0)
257
    gp_ptr=gp_ptr_backup+0x7ff0 ;
258
 
259
    /* #if 0 */
260
    /*Initialize the $gp register for sdata and sbss */
261
    printf("gp_ptr=0x%x ",gp_ptr);
262
    /*modify the first opcodes in boot.asm */
263
    /*modify the lui opcode */
264
    set_low(code,0,gp_ptr>>16);
265
    /*modify the ori opcode */
266
    set_low(code,4,gp_ptr&0xffff);
267
 
268
    /*Clear .sbss and .bss */
269
    printf("sbss=0x%x bss_end=0x%x\nlength=0x%x ",bss_start,bss_end,length);
270
    set_low(code,8,bss_start>>16);
271
    set_low(code,12,bss_start&0xffff);
272
    set_low(code,16,bss_end>>16);
273
    set_low(code,20,bss_end&0xffff);
274
 
275
    /*Set stack pointer */
276
    if(elfHeader->e_entry<0x10000000)
277
    stack_pointer=bss_end+512 ;
278
    else
279
    stack_pointer=bss_end+1024*4 ;
280
 
281
    if(stack_limit)stack_pointer=(stack_pointer<stack_limit)?stack_pointer:stack_limit ;
282
    //added by Liwei 2007-8-29
283
    stack_pointer&=~7 ;
284
    printf("SP=0x%x\n",stack_pointer);
285
    set_low(code,24,stack_pointer>>16);
286
    set_low(code,28,stack_pointer&0xffff);
287
    /* #endif */
288
 
289
    /*write out test.bin */
290
    outfile=fopen("test.bin","wb");
291
    fwrite(code,length,1,outfile);
292
    fclose(outfile);
293
 
294
 
295
    /*write out code.txt */
296
    txtfile=fopen("code.txt","w");
297
    for(i=0;i<=length;i+=4)
298
    {
299
        d=ntohl(*(unsigned long*)(code+i));
300
        fprintf(txtfile,"%8.8x\n",d);
301
    }
302
    fclose(txtfile);
303
    free(buf);
304
    printf("\n");
305
    return 0 ;
306
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.