source: umon/main/cpu/arm/ldatags.c @ 6e6815e

Last change on this file since 6e6815e was a7b6f00, checked in by Ed Sutter <edsutterjr@…>, on 08/04/15 at 01:35:50

tree cleanup using 'astyle --unpad-paren --align-pointer=name --lineend=linux --add-brackets --convert-tabs --style=knf -A4 FILENAME'

  • Property mode set to 100644
File size: 13.5 KB
Line 
1/**************************************************************************
2 *
3 * Copyright (c) 2013 Alcatel-Lucent
4 *
5 * Alcatel Lucent licenses this file to You under the Apache License,
6 * Version 2.0 (the "License"); you may not use this file except in
7 * compliance with the License.  A copy of the License is contained the
8 * file LICENSE at the top level of this repository.
9 * You may also obtain a copy of the License at:
10 *
11 *      http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 **************************************************************************
20 *
21 * ldatags:
22 *
23 * Load (install) ARM Tags for booting Linux.
24 *
25 * Original author:     Ed Sutter (ed.sutter@alcatel-lucent.com)
26 *
27 */
28#include "config.h"
29#include "stddefs.h"
30#include "genlib.h"
31#include "ether.h"
32#include "cli.h"
33#include "tfs.h"
34#include "tfsprivate.h"
35
36#define __PACKED__  __attribute__ ((packed))
37#define TAG_SIZE(a)     ((sizeof(a) + sizeof(struct tag_hdr))/4)
38#define STR_LEN(string) (sizeof(string) - 1)
39
40#define MEM32_SIZE      "mem32_size="
41#define MEM32_START     "mem32_start="
42#define CORE_FLAGS      "core_flags="
43#define CORE_PGSIZE     "core_pgsize="
44#define CORE_ROOTDEV    "core_rootdev="
45#define INITRD_SIZE     "initrd_size="
46#define INITRD_START    "initrd_start="
47#define RAMDISK_FLAGS   "ramdisk_flags="
48#define RAMDISK_SIZE    "ramdisk_size="
49#define RAMDISK_START   "ramdisk_start="
50#define SERIAL_HI       "serial_hi="
51#define SERIAL_LO       "serial_lo="
52#define CMDLINE         "cmdline="
53#define CMDLINE_APP     "cmdline_append="
54#define REVISION        "revision="
55
56void sno_mac_warning(int);
57void initrd_file_warning(int);
58
59#ifdef ATAG_SPACE_DEFINED
60extern int atag_space, end_atag_space;
61#endif
62
63#define CLISIZE         1024
64
65/* Tag specification defaults:
66 */
67#define RAMDISK_MAJOR   1
68#define PAGE_SIZE       4096
69#define PHYS_OFFSET     0x20000000
70#define MEM_SIZE        0x01e00000
71
72/* Tag identifiers:
73 */
74#define ATAG_NONE       0x00000000
75#define ATAG_CORE       0x54410001
76#define ATAG_MEM        0x54410002
77#define ATAG_VIDEOTEXT  0x54410003
78#define ATAG_RAMDISK    0x54410004
79#define ATAG_INITRD     0x54410005
80#define ATAG_INITRD2    0x54420005
81#define ATAG_SERIAL     0x54410006
82#define ATAG_REVISION   0x54410007
83#define ATAG_VIDEOLFB   0x54410008
84#define ATAG_CMDLINE    0x54410009
85#define ATAG_ACORN      0x41000101
86#define ATAG_MEMCLK     0x41000402
87#define ATAG_SNOMAC     ATAG_SERIAL
88
89/* Tag structures:
90 */
91struct tag_hdr {
92    ulong size;
93    ulong tag;
94} __PACKED__;
95
96struct tag_core {
97    ulong flags;
98    ulong pgsize;
99    ulong rootdev;
100} __PACKED__;
101
102struct tag_mem32 {
103    ulong size;
104    ulong start;
105} __PACKED__;
106
107union tag_snomac {
108    struct tag_serial {
109        ulong hi;
110        ulong lo;
111    } serial;
112    struct tag_mac {
113        char mac[8];    /* only use first 6 bytes */
114    } mac;
115} __PACKED__;
116
117struct tag_initrd {
118    ulong start;
119    ulong size;
120} __PACKED__;
121
122struct tag_ramdisk {
123    ulong flags;
124    ulong size;
125    ulong start;
126} __PACKED__;
127
128struct tag_cmdline {
129    char cmdline[CLISIZE];
130} __PACKED__;
131
132struct tag_revno {
133    ulong rev;
134} __PACKED__;
135
136struct init_tags {
137    struct tag_hdr      hdr1;
138    struct tag_core     core;
139    struct tag_hdr      hdr2;
140    struct tag_mem32    mem;
141    struct tag_hdr      hdr3;
142    union tag_snomac    snomac;
143    struct tag_hdr      hdr4;
144    struct tag_ramdisk  ramdisk;
145    struct tag_hdr      hdr5;
146    struct tag_initrd   initrd;
147    struct tag_hdr      hdr6;
148    struct tag_cmdline  cmdline;
149    struct tag_hdr      hdr7;
150    struct tag_revno    revno;
151    struct tag_hdr      hdr_last;
152} __PACKED__;
153
154/* This is the default tag list.  All entries in this list can
155 * be overridden by sub-commands within the ldatags command.
156 */
157static struct init_tags inittag = {
158    { TAG_SIZE(struct tag_core), ATAG_CORE },
159    { 1, PAGE_SIZE, 0xff },
160
161    { TAG_SIZE(struct tag_mem32), ATAG_MEM },
162    { MEM_SIZE, PHYS_OFFSET },
163
164    { TAG_SIZE(union tag_snomac), ATAG_SNOMAC },
165    { {0xffffffff, 0xffffffff} },
166
167    { TAG_SIZE(struct tag_ramdisk), ATAG_RAMDISK },
168    { 0, 0, 0 },
169
170    { TAG_SIZE(struct tag_initrd), ATAG_INITRD2 },
171    { 0, 0 },
172
173    { TAG_SIZE(struct tag_cmdline), ATAG_CMDLINE },
174    { {0} },
175
176    { TAG_SIZE(struct tag_revno), ATAG_REVISION },
177    { 0 },
178
179    { 0, ATAG_NONE },
180};
181
182
183char *ldatagsHelp[] = {
184    "Install ARM tags for Linux startup.",
185    "[-a:cf:imv] [sub-cmd1 sub-cmd2 ...]",
186    "Options:",
187    " -a {addr}    tag list address",
188    " -c           clear tag list memory",
189    " -f {fname}   initrd filename",
190    " -i           init default tag list",
191    " -m           load MAC address into serial_no tag",
192    " -v           enable verbosity",
193    "Sub-commands:",
194    "   " CORE_FLAGS "{value}",
195    "   " CORE_PGSIZE "{value}",
196    "   " CORE_ROOTDEV "{value}",
197    "   " MEM32_SIZE "{value}",
198    "   " MEM32_START "{value}",
199    "   " SERIAL_LO "{value}       (serial hi/lo overrides -m)",
200    "   " SERIAL_HI "{value}",
201    "   " INITRD_SIZE "{value}     (initrd size/start overrides -f)",
202    "   " INITRD_START "{value}",
203    "   " RAMDISK_FLAGS "{value}",
204    "   " RAMDISK_SIZE "{value}",
205    "   " RAMDISK_START "{value}",
206    "   " REVISION "{value}",
207    "   " CMDLINE "{string}",
208    "   " CMDLINE_APP "{string}",
209    0
210};
211
212
213int
214ldatags(int argc,char *argv[])
215{
216    TFILE   *tfp;
217    char    *eadd, *initrd_fname;
218    struct init_tags *tagaddr;
219    int     opt, verbose, arg, clear, init, mac, len;
220    int     sno_mac_warned, initrd_file_warned;
221
222    initrd_fname = 0;
223    sno_mac_warned = initrd_file_warned = 0;
224    mac = init = verbose = clear = 0;
225#ifdef ATAG_SPACE_DEFINED
226    tagaddr = (struct init_tags *)&atag_space;
227#else
228    tagaddr = (struct init_tags *)getAppRamStart();
229#endif
230    while((opt=getopt(argc,argv,"a:cf:imv")) != -1) {
231        switch(opt) {
232        case 'a':   /* Override default tag list address. */
233            tagaddr = (struct init_tags *)strtoul(optarg,0,0);
234            break;
235        case 'c':   /* Clear the tag list space. */
236            clear++;
237            break;
238        case 'f':   /* Initrd filename. */
239            initrd_fname = optarg;
240            break;
241        case 'i':   /* Initialize tag list with defaults. */
242            init++;
243            break;
244        case 'm':   /* Load MAC address into list. */
245            mac++;
246            break;
247        case 'v':   /* Enable verbosity. */
248            verbose++;
249            break;
250        default:
251            return(CMD_PARAM_ERROR);
252        }
253    }
254
255#ifdef ATAG_SPACE_DEFINED
256    /* If the ATAG space is allocated externally (usually in rom.lnk file),
257     * then if at this point the tag address still points to that space,
258     * we must start by verifying that the allocated space is large enough
259     * to hold the init_tags structure...
260     */
261    if(tagaddr == (struct init_tags *)&atag_space) {
262        if(((int)&end_atag_space - (int)&atag_space) < sizeof(struct init_tags)) {
263            printf("Error: the size of struct init_tags (%d) is larger than\n",
264                   sizeof(struct init_tags));
265            printf("       the size of the allocated atag space (%d bytes).\n",
266                   ((int)&end_atag_space - (int)&atag_space));
267            return(CMD_FAILURE);
268        }
269    }
270#endif
271
272    if(clear) {
273        memset((char *)tagaddr,0,sizeof(struct init_tags));
274        if(verbose) {
275            printf("Tagspace at 0x%lx cleared\n",(long)tagaddr);
276        }
277        return(CMD_SUCCESS);
278    }
279
280    /* If -i specified, then load default tag list for starters...
281     */
282    if(init) {
283        memcpy((char *)tagaddr,(char *)&inittag,sizeof(struct init_tags));
284    }
285
286    /* Insert this board's MAC address:
287     */
288    if(mac) {
289        memset(tagaddr->snomac.mac.mac,0,8);
290        eadd = getenv("ETHERADD");
291        if(eadd) {
292            if(EtherToBin(eadd,(uchar *)tagaddr->snomac.mac.mac) < 0) {
293                return(CMD_FAILURE);
294            }
295        } else {
296            printf("ETHERADD shell var not set.\n");
297            return(CMD_FAILURE);
298        }
299    }
300
301    if(initrd_fname) {
302        tfp = tfsstat(initrd_fname);
303        if(!tfp) {
304            printf("No such file: %s\n",initrd_fname);
305            return(CMD_FAILURE);
306        }
307        tagaddr->initrd.size = (ulong)TFS_SIZE(tfp);
308        tagaddr->initrd.start = (ulong)TFS_BASE(tfp);
309    }
310
311    /* Process the command line arguments:
312     */
313    for(arg=optind; arg<argc; arg++) {
314        if(strncmp(argv[arg],CORE_FLAGS,STR_LEN(CORE_FLAGS)) == 0) {
315            tagaddr->core.flags =
316                strtoul(argv[arg]+STR_LEN(CORE_FLAGS),0,0);
317        } else if(strncmp(argv[arg],CORE_PGSIZE,STR_LEN(CORE_PGSIZE)) == 0) {
318            tagaddr->core.pgsize =
319                strtoul(argv[arg]+STR_LEN(CORE_PGSIZE),0,0);
320        } else if(strncmp(argv[arg],CORE_ROOTDEV,STR_LEN(CORE_ROOTDEV)) == 0) {
321            tagaddr->core.rootdev =
322                strtoul(argv[arg]+STR_LEN(CORE_ROOTDEV),0,0);
323        } else if(strncmp(argv[arg],MEM32_SIZE,STR_LEN(MEM32_SIZE)) == 0) {
324            tagaddr->mem.size =
325                strtoul(argv[arg]+STR_LEN(MEM32_SIZE),0,0);
326        } else if(strncmp(argv[arg],MEM32_START,STR_LEN(MEM32_START)) == 0) {
327            tagaddr->mem.start =
328                strtoul(argv[arg]+STR_LEN(MEM32_START),0,0);
329        } else if(strncmp(argv[arg],INITRD_SIZE,STR_LEN(INITRD_SIZE)) == 0) {
330            if(initrd_fname) {
331                initrd_file_warning(initrd_file_warned++);
332            }
333            tagaddr->initrd.size =
334                strtoul(argv[arg]+STR_LEN(INITRD_SIZE),0,0);
335        } else if(strncmp(argv[arg],INITRD_START,STR_LEN(INITRD_START)) == 0) {
336            if(initrd_fname) {
337                initrd_file_warning(initrd_file_warned++);
338            }
339            tagaddr->initrd.start =
340                strtoul(argv[arg]+STR_LEN(INITRD_START),0,0);
341        } else if(strncmp(argv[arg],RAMDISK_FLAGS,STR_LEN(RAMDISK_FLAGS)) == 0) {
342            tagaddr->ramdisk.flags =
343                strtoul(argv[arg]+STR_LEN(RAMDISK_FLAGS),0,0);
344        } else if(strncmp(argv[arg],RAMDISK_SIZE,STR_LEN(RAMDISK_SIZE)) == 0) {
345            tagaddr->ramdisk.size =
346                strtoul(argv[arg]+STR_LEN(RAMDISK_SIZE),0,0);
347        } else if(strncmp(argv[arg],RAMDISK_START,STR_LEN(RAMDISK_START)) == 0) {
348            tagaddr->ramdisk.start =
349                strtoul(argv[arg]+STR_LEN(RAMDISK_START),0,0);
350        } else if(strncmp(argv[arg],SERIAL_HI,STR_LEN(SERIAL_HI)) == 0) {
351            if(mac) {
352                sno_mac_warning(sno_mac_warned++);
353            }
354            mac = 0;
355            tagaddr->snomac.serial.hi =
356                strtoul(argv[arg]+STR_LEN(SERIAL_HI),0,0);
357        } else if(strncmp(argv[arg],SERIAL_LO,STR_LEN(SERIAL_LO)) == 0) {
358            if(mac) {
359                sno_mac_warning(sno_mac_warned++);
360            }
361            mac = 0;
362            tagaddr->snomac.serial.lo =
363                strtoul(argv[arg]+STR_LEN(SERIAL_LO),0,0);
364        } else if(strncmp(argv[arg],CMDLINE,STR_LEN(CMDLINE)) == 0) {
365            len = strlen(argv[arg]+STR_LEN(CMDLINE));
366            if(len > CLISIZE-1) {
367                printf("Kernel cli too big (%d>%d)\n",len,CLISIZE);
368            } else {
369                strcpy(tagaddr->cmdline.cmdline,argv[arg]+STR_LEN(CMDLINE));
370            }
371        } else if(strncmp(argv[arg],CMDLINE_APP,STR_LEN(CMDLINE_APP)) == 0) {
372            len = strlen(argv[arg]+STR_LEN(CMDLINE_APP));
373            len += strlen(tagaddr->cmdline.cmdline);
374            if(len > CLISIZE-1) {
375                printf("Kernel cli too big (%d>%d)\n",len,CLISIZE);
376            } else {
377                strcat(tagaddr->cmdline.cmdline,argv[arg]+STR_LEN(CMDLINE_APP));
378            }
379        } else if(strncmp(argv[arg],REVISION,STR_LEN(REVISION)) == 0) {
380            tagaddr->revno.rev =
381                strtoul(argv[arg]+STR_LEN(REVISION),0,0);
382        } else {
383            printf("Unrecognized sub-command: %s\n",argv[arg]);
384            return(CMD_FAILURE);
385        }
386    }
387
388    if(verbose) {
389        printf("ATAGS (%d bytes) at 0x%lx...\n",
390               sizeof(struct init_tags),(long)tagaddr);
391        printf(" Core (flags/pgsize/rootdev) = 0x%lx/0x%0lx/0x%lx\n",
392               tagaddr->core.flags,tagaddr->core.pgsize,tagaddr->core.rootdev);
393        printf(" Mem32 (size/offset) = 0x%08lx/0x%08lx\n",
394               tagaddr->mem.size,tagaddr->mem.start);
395        if(mac) {
396            printf(" Mac = %02x:%02x:%02x:%02x:%02x:%02x\n",
397                   tagaddr->snomac.mac.mac[0], tagaddr->snomac.mac.mac[1],
398                   tagaddr->snomac.mac.mac[2], tagaddr->snomac.mac.mac[3],
399                   tagaddr->snomac.mac.mac[4], tagaddr->snomac.mac.mac[5]);
400        } else {
401            printf(" Serial (hi/lo) = 0x%08lx/0x%08lx\n",
402                   tagaddr->snomac.serial.hi, tagaddr->snomac.serial.lo);
403        }
404        printf(" Ramdisk (flags/size/start) = 0x%lx/0x%lx/0x%lx\n",
405               tagaddr->ramdisk.flags, tagaddr->ramdisk.size,
406               tagaddr->ramdisk.start);
407
408        printf(" Initrd (size/start) = 0x%lx/0x%lx\n",
409               tagaddr->initrd.size, tagaddr->initrd.start);
410
411        printf(" Cmdline = <%s>\n",tagaddr->cmdline.cmdline);
412    }
413
414    return(CMD_SUCCESS);
415}
416
417void
418sno_mac_warning(int already_warned)
419{
420    if(already_warned) {
421        return;
422    }
423
424    printf("Warning: serialno command overrides -m option.\n");
425}
426
427void
428initrd_file_warning(int already_warned)
429{
430    if(already_warned) {
431        return;
432    }
433
434    printf("Warning: initrd command overrides -f option.\n");
435}
Note: See TracBrowser for help on using the repository browser.