uboot/arch/nds32/lib/bootm.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2011 Andes Technology Corporation
   3 * Shawn Lin, Andes Technology Corporation <nobuhiro@andestech.com>
   4 * Macpaul Lin, Andes Technology Corporation <macpaul@andestech.com>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#include <common.h>
  10#include <command.h>
  11#include <image.h>
  12#include <u-boot/zlib.h>
  13#include <asm/byteorder.h>
  14#include <asm/bootm.h>
  15
  16DECLARE_GLOBAL_DATA_PTR;
  17
  18int arch_fixup_fdt(void *blob)
  19{
  20        return 0;
  21}
  22
  23
  24#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
  25        defined(CONFIG_CMDLINE_TAG) || \
  26        defined(CONFIG_INITRD_TAG) || \
  27        defined(CONFIG_SERIAL_TAG) || \
  28        defined(CONFIG_REVISION_TAG)
  29static void setup_start_tag(bd_t *bd);
  30
  31# ifdef CONFIG_SETUP_MEMORY_TAGS
  32static void setup_memory_tags(bd_t *bd);
  33# endif
  34static void setup_commandline_tag(bd_t *bd, char *commandline);
  35
  36# ifdef CONFIG_INITRD_TAG
  37static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end);
  38# endif
  39static void setup_end_tag(bd_t *bd);
  40
  41static struct tag *params;
  42#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
  43
  44int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
  45{
  46        bd_t    *bd = gd->bd;
  47        char    *s;
  48        int     machid = bd->bi_arch_number;
  49        void    (*theKernel)(int zero, int arch, uint params);
  50
  51#ifdef CONFIG_CMDLINE_TAG
  52        char *commandline = env_get("bootargs");
  53#endif
  54
  55        /*
  56         * allow the PREP bootm subcommand, it is required for bootm to work
  57         */
  58        if (flag & BOOTM_STATE_OS_PREP)
  59                return 0;
  60
  61        if ((flag != 0) && (flag != BOOTM_STATE_OS_GO))
  62                return 1;
  63
  64        theKernel = (void (*)(int, int, uint))images->ep;
  65
  66        s = env_get("machid");
  67        if (s) {
  68                machid = simple_strtoul(s, NULL, 16);
  69                printf("Using machid 0x%x from environment\n", machid);
  70        }
  71
  72        bootstage_mark(BOOTSTAGE_ID_RUN_OS);
  73
  74        debug("## Transferring control to Linux (at address %08lx) ...\n",
  75               (ulong)theKernel);
  76
  77        if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len) {
  78#ifdef CONFIG_OF_LIBFDT
  79                debug("using: FDT\n");
  80                if (image_setup_linux(images)) {
  81                        printf("FDT creation failed! hanging...");
  82                        hang();
  83                }
  84#endif
  85        } else if (BOOTM_ENABLE_TAGS) {
  86#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
  87        defined(CONFIG_CMDLINE_TAG) || \
  88        defined(CONFIG_INITRD_TAG) || \
  89        defined(CONFIG_SERIAL_TAG) || \
  90        defined(CONFIG_REVISION_TAG)
  91        setup_start_tag(bd);
  92#ifdef CONFIG_SERIAL_TAG
  93        setup_serial_tag(&params);
  94#endif
  95#ifdef CONFIG_REVISION_TAG
  96        setup_revision_tag(&params);
  97#endif
  98#ifdef CONFIG_SETUP_MEMORY_TAGS
  99        setup_memory_tags(bd);
 100#endif
 101#ifdef CONFIG_CMDLINE_TAG
 102        setup_commandline_tag(bd, commandline);
 103#endif
 104#ifdef CONFIG_INITRD_TAG
 105        if (images->rd_start && images->rd_end)
 106                setup_initrd_tag(bd, images->rd_start, images->rd_end);
 107#endif
 108        setup_end_tag(bd);
 109#endif
 110
 111        /* we assume that the kernel is in place */
 112        printf("\nStarting kernel ...\n\n");
 113
 114#ifdef CONFIG_USB_DEVICE
 115        {
 116                extern void udc_disconnect(void);
 117                udc_disconnect();
 118        }
 119#endif
 120        }
 121        cleanup_before_linux();
 122        if (IMAGE_ENABLE_OF_LIBFDT && images->ft_len)
 123                theKernel(0, machid, (unsigned long)images->ft_addr);
 124        else
 125                theKernel(0, machid, bd->bi_boot_params);
 126        /* does not return */
 127
 128        return 1;
 129}
 130
 131#if defined(CONFIG_SETUP_MEMORY_TAGS) || \
 132        defined(CONFIG_CMDLINE_TAG) || \
 133        defined(CONFIG_INITRD_TAG) || \
 134        defined(CONFIG_SERIAL_TAG) || \
 135        defined(CONFIG_REVISION_TAG)
 136static void setup_start_tag(bd_t *bd)
 137{
 138        params = (struct tag *)bd->bi_boot_params;
 139
 140        params->hdr.tag = ATAG_CORE;
 141        params->hdr.size = tag_size(tag_core);
 142
 143        params->u.core.flags = 0;
 144        params->u.core.pagesize = 0;
 145        params->u.core.rootdev = 0;
 146
 147        params = tag_next(params);
 148}
 149
 150#ifdef CONFIG_SETUP_MEMORY_TAGS
 151static void setup_memory_tags(bd_t *bd)
 152{
 153        int i;
 154
 155        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
 156                params->hdr.tag = ATAG_MEM;
 157                params->hdr.size = tag_size(tag_mem32);
 158
 159                params->u.mem.start = bd->bi_dram[i].start;
 160                params->u.mem.size = bd->bi_dram[i].size;
 161
 162                params = tag_next(params);
 163        }
 164}
 165#endif /* CONFIG_SETUP_MEMORY_TAGS */
 166
 167static void setup_commandline_tag(bd_t *bd, char *commandline)
 168{
 169        char *p;
 170
 171        if (!commandline)
 172                return;
 173
 174        /* eat leading white space */
 175        for (p = commandline; *p == ' '; p++)
 176                ;
 177
 178        /* skip non-existent command lines so the kernel will still
 179         * use its default command line.
 180         */
 181        if (*p == '\0')
 182                return;
 183
 184        params->hdr.tag = ATAG_CMDLINE;
 185        params->hdr.size =
 186                (sizeof(struct tag_header) + strlen(p) + 1 + 4) >> 2;
 187
 188        strcpy(params->u.cmdline.cmdline, p)
 189                ;
 190
 191        params = tag_next(params);
 192}
 193
 194#ifdef CONFIG_INITRD_TAG
 195static void setup_initrd_tag(bd_t *bd, ulong initrd_start, ulong initrd_end)
 196{
 197        /* an ATAG_INITRD node tells the kernel where the compressed
 198         * ramdisk can be found. ATAG_RDIMG is a better name, actually.
 199         */
 200        params->hdr.tag = ATAG_INITRD2;
 201        params->hdr.size = tag_size(tag_initrd);
 202
 203        params->u.initrd.start = initrd_start;
 204        params->u.initrd.size = initrd_end - initrd_start;
 205
 206        params = tag_next(params);
 207}
 208#endif /* CONFIG_INITRD_TAG */
 209
 210#ifdef CONFIG_SERIAL_TAG
 211void setup_serial_tag(struct tag **tmp)
 212{
 213        struct tag *params = *tmp;
 214        struct tag_serialnr serialnr;
 215        void get_board_serial(struct tag_serialnr *serialnr);
 216
 217        get_board_serial(&serialnr);
 218        params->hdr.tag = ATAG_SERIAL;
 219        params->hdr.size = tag_size(tag_serialnr);
 220        params->u.serialnr.low = serialnr.low;
 221        params->u.serialnr.high = serialnr.high;
 222        params = tag_next(params);
 223        *tmp = params;
 224}
 225#endif
 226
 227#ifdef CONFIG_REVISION_TAG
 228void setup_revision_tag(struct tag **in_params)
 229{
 230        u32 rev = 0;
 231        u32 get_board_rev(void);
 232
 233        rev = get_board_rev();
 234        params->hdr.tag = ATAG_REVISION;
 235        params->hdr.size = tag_size(tag_revision);
 236        params->u.revision.rev = rev;
 237        params = tag_next(params);
 238}
 239#endif  /* CONFIG_REVISION_TAG */
 240
 241static void setup_end_tag(bd_t *bd)
 242{
 243        params->hdr.tag = ATAG_NONE;
 244        params->hdr.size = 0;
 245}
 246
 247#endif /* CONFIG_SETUP_MEMORY_TAGS || CONFIG_CMDLINE_TAG || CONFIG_INITRD_TAG */
 248