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

Subversion Repositories amber

[/] [amber/] [trunk/] [sw/] [boot-loader-serial/] [boot-loader-serial.c] - Blame information for rev 67

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 csantifort
/*----------------------------------------------------------------
2
//                                                              //
3
//  boot-loader.c                                               //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  The main functions for the boot loader application. This    //
10
//  application is embedded in the FPGA's SRAM and is used      //
11
//  to load larger applications into the DDR3 memory on         //
12
//  the development board.                                      //
13
//                                                              //
14
//  Author(s):                                                  //
15
//      - Conor Santifort, csantifort.amber@gmail.com           //
16
//                                                              //
17
//////////////////////////////////////////////////////////////////
18
//                                                              //
19
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
20
//                                                              //
21
// This source file may be used and distributed without         //
22
// restriction provided that this copyright statement is not    //
23
// removed from the file and that any derivative work contains  //
24
// the original copyright notice and the associated disclaimer. //
25
//                                                              //
26
// This source file is free software; you can redistribute it   //
27
// and/or modify it under the terms of the GNU Lesser General   //
28
// Public License as published by the Free Software Foundation; //
29
// either version 2.1 of the License, or (at your option) any   //
30
// later version.                                               //
31
//                                                              //
32
// This source is distributed in the hope that it will be       //
33
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
34
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
35
// PURPOSE.  See the GNU Lesser General Public License for more //
36
// details.                                                     //
37
//                                                              //
38
// You should have received a copy of the GNU Lesser General    //
39
// Public License along with this source; if not, download it   //
40
// from http://www.opencores.org/lgpl.shtml                     //
41
//                                                              //
42
----------------------------------------------------------------*/
43
 
44
#include "amber_registers.h"
45
#include "stdio.h"
46
#include "boot-loader.h"
47
#include "fpga-version.h"
48
 
49
 
50
int main ( void ) {
51
    int c, esc = 0;
52
    char buf  [20]; /* current line */
53
    char lbuf [20]; /* last line    */
54
    int i = 0;
55
    int li = 0;
56
    int j;
57
 
58
    /* Enable the UART FIFO */
59
    *(unsigned int *) ADR_AMBER_UART0_LCRH = 0x10;
60
 
61
    printf("%cAmber Boot Loader v%s\n", 0xc, AMBER_FPGA_VERSION );  /* 0xc == new page */
62
 
63 11 csantifort
 
64
    /* When ADR_AMBER_TEST_SIM_CTRL is non-zero, its a Verilog simulation.
65
       The  ADR_AMBER_TEST_SIM_CTRL register is always 0 in the real fpga
66 2 csantifort
       The register is in vlog/system/test_module.v
67
    */
68 11 csantifort
    if ( *(unsigned int *) ADR_AMBER_TEST_SIM_CTRL ) {
69
        load_run(*(unsigned int *) ADR_AMBER_TEST_SIM_CTRL, 0);
70 2 csantifort
        }
71 11 csantifort
 
72 2 csantifort
 
73 11 csantifort
    /* Print the instructions */
74
    print_help();
75
    printf("Ready\n> ");
76 2 csantifort
 
77
    /* Loop forever on user input */
78
    while (1) {
79
        if ((c = _inbyte (DLY_1S)) >= 0) {
80
 
81
            /* Escape Sequence ? */
82
            if (c == 0x1b) esc = 1;
83
            else if (esc == 1 && c == 0x5b) esc = 2;
84
            else if (esc == 2) {
85
                esc = 0;
86
                if (c == 'A') {
87
                    /* Erase current line using backspaces */
88
                    for (j=0;j<i;j++)  _outbyte(0x08);
89
 
90
                    /* print last line and
91
                       make current line equal to last line  */
92
                    for (j=0;j<li;j++) _outbyte(buf[j] = lbuf[j]);
93
                    i = li;
94
                    }
95
                continue;
96
                }
97
            else esc = 0;
98
 
99
            /* Character not part of escape sequence so print it
100
               and add it to the buffer
101
            */
102
            if (!esc) {
103
                _outbyte (c);
104
                /* Backspace ? */
105
                if (c == 8 && i > 0) { i--; }
106
                else                 { buf[i++] = c; }
107
                }
108
 
109
            /* End of line ? */
110
            if (c == '\r' || i >= 19) {
111
                if (i>1) {
112
                    /* Copy current line buffer to last line buffer */
113
                    for (j=0;j<20;j++) lbuf[j] = buf[j];
114
                    li = i-1;
115
                    }
116
                buf[i] = 0; i = 0;
117
 
118
                /* Process line */
119
                printf("\n");
120
                parse( buf );
121
                printf("> ");
122
                }
123
            }
124
        }
125
}
126
 
127
 
128
/* Parse a command line passed from main and execute the command */
129
void parse ( char * buf )
130
{
131
    unsigned int found, address, data, i, length, bytes, rdata;
132
    int file_size;
133
    char byte;
134
    unsigned int lcount;
135
    char bad_command_msg[] = "Invalid command";
136
 
137
    /* Ignore returns with no trext on the line */
138
    if (!buf[1]) return;
139
 
140
    /* Check if its a single character instruction */
141
    if (buf[1] == '\r') {
142
        switch (buf[0]) {
143
 
144
            case 'h': /* Help */
145
                print_help();
146
                break;
147
 
148
            case 'l': /* Load */
149 11 csantifort
                load_run(1,0);
150 2 csantifort
                break;
151
 
152
            case 's': /* Status */
153
                _core_status();
154
                /* Flush out the uart with spaces */
155
                print_spaces(16);
156
                printf  ("\n");
157
                break;
158
 
159
            default:
160
                printf  ("%s\n", bad_command_msg);
161
                break;
162
            }
163
        return;
164
        }
165
 
166
 
167
    /* Check for invalid instruction format for multi-word instructions */
168
    else if (buf[1] != 0x20) {
169
        printf ("%s\n", bad_command_msg);
170
        return;
171
        }
172
 
173
 
174
    switch (buf[0]) {
175
 
176
            case 'd': /* Dump block of memory */
177
                /* Dump memory contents <start address> <number of bytes in hex> */
178
                if (get_address_data ( buf, &address, &bytes )) {
179
                    for (i=address;i<address+bytes;i+=4) {
180
                        printm (i);
181
                        }
182
                    }
183
                break;
184
 
185 48 csantifort
            case 'j': /* Jump to <address> */
186
                if (get_hex ( buf, 2, &address, &length )) {
187
                    load_run(0, address);
188
                    }
189
                break;
190
 
191
 
192 2 csantifort
            case 'p': /* Print String */
193
                /* Recover the address from the string - the address is written in hex */
194
                if (get_hex ( buf, 2, &address, &length )) {
195
                    length = 0;
196
                    lcount = 0;
197
                    byte = * (char *)address++;
198
                    while ( byte < 128 && length < 0x1000 ) {
199
 
200
                        if ( byte != 0 )        _outbyte( byte );
201
                        if ( byte  == '\r' )    printf("\n"); lcount = 0;
202
                        if ( lcount == 79 )     printf("\n"); lcount = 0;
203
 
204
                        byte = * (char *)address++;
205
                        lcount++;
206
                        length++;
207
                        }
208
                    }
209
                break;
210
 
211
            case 'r': /* Read address */
212
                /* Recover the address from the string - the address is written in hex */
213
                if (get_hex ( buf, 2, &address, &length )) {
214
                    printm (address);
215
                    }
216
                break;
217
 
218 11 csantifort
            case 'b': /* Load binary file into address */
219
                /* Recover the address from the string - the address is written in hex */
220
                if (get_hex ( buf, 2, &address, &length )) {
221
                    load_run (5, address);
222
                    }
223
                break;
224
 
225 2 csantifort
            case 'w': /* Write address */
226
                /* Get the address */
227
                if (get_address_data ( buf, &address, &data )) {
228
                    /* Write to memory */
229
                    * (unsigned int*) address = data;
230
                    /* read back */
231
                    printm (address);
232
                    }
233
                break;
234
 
235
            default:
236
                printf  ("%s\n", bad_command_msg);
237
                break;
238
        }
239
}
240
 
241
 
242 11 csantifort
/* Load a binary file into memory via the UART
243
   If its an elf file, copy it into the correct memory areas
244
   and execute it.
245
*/
246
void load_run( int type, unsigned int address )
247 2 csantifort
{
248
    int file_size;
249 43 csantifort
    char * message = "Send file w/ 1K Xmodem protocol from terminal emulator now...";
250 48 csantifort
 
251
    switch (type) {
252 11 csantifort
 
253 48 csantifort
        case 1: /* Load a binary file to FILE_LOAD_BASE */
254
            /* Load a file using the xmodem protocol */
255
            printf  ("%s\n", message);
256 11 csantifort
 
257 48 csantifort
                                      /*       Destination,    Destination Size */
258
            file_size = xmodemReceive((char *) FILE_LOAD_BASE, FILE_MAX_SIZE);
259
            if (file_size < 0 || file_size > FILE_MAX_SIZE) {
260
                printf ("Xmodem error file size 0x%x \n", file_size);
261
                return;
262
                }
263
 
264
            printf("\nelf split\n");
265
            elfsplitter(FILE_LOAD_BASE, file_size);
266
            break;
267
 
268 11 csantifort
 
269 48 csantifort
        case 2: /* testing the boot loader itself in simulation */
270
            print_help();
271
            _core_status();
272
            print_spaces(16);
273
            _testpass();
274
            break;
275 11 csantifort
 
276
 
277 48 csantifort
        case 3: /* vmlinux in simulation */
278
            printf("j 0x%08x\n", LINUX_JUMP_ADR);
279
            /* Flush the uart tx buffer with spaces */
280
            print_spaces(16);
281
            printf("\n");
282
            /* pc jump */
283
            _jump_to_program(LINUX_JUMP_ADR);
284
            _testpass();
285
            break;
286 11 csantifort
 
287 48 csantifort
 
288
        case 4: /* programs starting at 0x8000 in simulation */
289
            printf("j 0x%08x\n", APP_JUMP_ADR);
290
            /* Flush the uart tx buffer with spaces */
291
            print_spaces(16);
292
            printf("\n");
293
            /* pc jump */
294
            _jump_to_program(APP_JUMP_ADR);
295
            _testpass();
296
            break;
297
 
298
 
299
        case 5: /* Load a binary file into memory, to 'address' */
300
            /* Load a file using the xmodem protocol */
301
            printf  ("%s\n", message);
302
                                      /*       Destination,    Destination Size */
303
            file_size = xmodemReceive((char *) address, FILE_MAX_SIZE);
304
            if (file_size < 0 || file_size > FILE_MAX_SIZE) {
305
                printf ("Xmodem error file size 0x%x \n", file_size);
306
                return;
307
                }
308
            break;
309
 
310
 
311
        default:    /* Run the program */
312
            printf("j 0x%08x\n", address);
313
            /* Flush the uart tx buffer with spaces */
314
            print_spaces(16);
315
            printf("\n");
316
            /* pc jump */
317
            _jump_to_program(address);
318
            _testpass();
319
            break;
320 2 csantifort
        }
321
}
322
 
323
 
324
/* Print a memory location */
325
void printm ( unsigned int address )
326
{
327
    printf ("mem 0x%08x = 0x%08x\n", address, * (unsigned int *)address);
328
}
329
 
330
 
331
void print_help ( void )
332
 
333
{
334
    printf("Commands\n");
335
    printf("l");
336
    print_spaces(29);
337
    printf(": Load elf file\n");
338
 
339 11 csantifort
    printf("b <address>");
340
    print_spaces(19);
341
    printf(": Load binary file to <address>\n");
342
 
343 2 csantifort
    printf("d <start address> <num bytes> : Dump mem\n");
344
 
345
    printf("h");
346
    print_spaces(29);
347
    printf(": Print help message\n");
348
 
349 48 csantifort
    printf("j <address>");
350
    print_spaces(19);
351
    printf(": Execute loaded elf, jumping to <address>\n");
352 2 csantifort
 
353
    printf("p <address>");
354
    print_spaces(19);
355
    printf(": Print ascii mem until first 0\n");
356
 
357
    printf("r <address>");
358
    print_spaces(19);
359
    printf(": Read mem\n");
360
 
361
    printf("s");
362
    print_spaces(29);
363
    printf(": Core status\n");
364
 
365
    printf("w <address> <value>");
366
    print_spaces(11);
367 11 csantifort
    printf(": Write mem\n");
368 2 csantifort
}
369
 
370
 
371
/* Print a number of spaces */
372
void print_spaces ( int num )
373
{
374
    while(num--) printf(" ");
375
}
376
 
377
 
378
/* Return a number recovered from a string of hex digits */
379
int get_hex ( char * buf, int start_position,
380
              unsigned int *address,
381
              unsigned int *length)
382
{
383
 
384
    int cpos = 0, done = 0;
385
 
386
    cpos = start_position; done = 0; *address = 0;
387
 
388
    while (done == 0) {
389
        if ( buf[cpos] >= '0' && buf[cpos] <= '9' ) {
390
           *address = *address<<4;
391
           *address = *address + buf[cpos] - '0';
392
           }
393
        else if ( buf[cpos] >= 'A' && buf[cpos] <= 'F' ) {
394
            *address = *address<<4;
395
            *address = *address + buf[cpos] - 'A' + 10;
396
           }
397
        else if ( buf[cpos] >= 'a' && buf[cpos] <= 'f' ) {
398
            *address = *address<<4;
399
            *address = *address + buf[cpos] - 'a' + 10;
400
           }
401
        else  {
402
            done = 1;
403
            *length = cpos - start_position;
404
            }
405
        if ( cpos >= 8+start_position ) {
406
            done = 1;
407
            *length = 8;
408
            }
409
        cpos++;
410
        }
411
 
412
    /* Return the length of the hexadecimal string */
413
    if (cpos > start_position+1) return 1; else return 0;
414
}
415
 
416
 
417
/* Parse a string for an address and data in hex */
418
int get_address_data ( char * buf, unsigned int *address, unsigned int *data )
419
{
420
    int found, length;
421
 
422
    found = get_hex ( buf, 2, address, &length );
423
    if (found) {
424
        /* Get the data */
425
        found = get_hex ( buf, 3+length, data, &length );
426
        }
427
 
428
    return found;
429
}
430
 

powered by: WebSVN 2.1.0

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