uboot/arch/xtensa/lib/bootm.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2008 - 2013 Tensilica Inc.
   3 * (C) Copyright 2014 Cadence Design Systems Inc.
   4 *
   5 * SPDX-License-Identifier:     GPL-2.0+
   6 */
   7
   8#include <common.h>
   9#include <command.h>
  10#include <u-boot/zlib.h>
  11#include <asm/byteorder.h>
  12#include <asm/addrspace.h>
  13#include <asm/bootparam.h>
  14#include <asm/cache.h>
  15#include <image.h>
  16
  17DECLARE_GLOBAL_DATA_PTR;
  18
  19/*
  20 * Setup boot-parameters.
  21 */
  22
  23static struct bp_tag *setup_first_tag(struct bp_tag *params)
  24{
  25        params->id = BP_TAG_FIRST;
  26        params->size = sizeof(long);
  27        *(unsigned long *)&params->data = BP_VERSION;
  28
  29        return bp_tag_next(params);
  30}
  31
  32static struct bp_tag *setup_last_tag(struct bp_tag *params)
  33{
  34        params->id = BP_TAG_LAST;
  35        params->size = 0;
  36
  37        return bp_tag_next(params);
  38}
  39
  40static struct bp_tag *setup_memory_tag(struct bp_tag *params)
  41{
  42        struct bd_info *bd = gd->bd;
  43        struct meminfo *mem;
  44
  45        params->id = BP_TAG_MEMORY;
  46        params->size = sizeof(struct meminfo);
  47        mem = (struct meminfo *)params->data;
  48        mem->type = MEMORY_TYPE_CONVENTIONAL;
  49        mem->start = bd->bi_memstart;
  50        mem->end = bd->bi_memstart + bd->bi_memsize;
  51
  52        printf("   MEMORY:          tag:0x%04x, type:0X%lx, start:0X%lx, end:0X%lx\n",
  53               BP_TAG_MEMORY, mem->type, mem->start, mem->end);
  54
  55        return bp_tag_next(params);
  56}
  57
  58static struct bp_tag *setup_commandline_tag(struct bp_tag *params,
  59                                            char *cmdline)
  60{
  61        int len;
  62
  63        if (!cmdline)
  64                return params;
  65
  66        len = strlen(cmdline);
  67
  68        params->id = BP_TAG_COMMAND_LINE;
  69        params->size = (len + 3) & -4;
  70        strcpy((char *)params->data, cmdline);
  71
  72        printf("   COMMAND_LINE:    tag:0x%04x, size:%u, data:'%s'\n",
  73               BP_TAG_COMMAND_LINE, params->size, cmdline);
  74
  75        return bp_tag_next(params);
  76}
  77
  78static struct bp_tag *setup_ramdisk_tag(struct bp_tag *params,
  79                                        unsigned long rd_start,
  80                                        unsigned long rd_end)
  81{
  82        struct meminfo *mem;
  83
  84        if (rd_start == rd_end)
  85                return params;
  86
  87        /* Add a single banked memory */
  88
  89        params->id = BP_TAG_INITRD;
  90        params->size = sizeof(struct meminfo);
  91
  92        mem = (struct meminfo *)params->data;
  93        mem->type =  MEMORY_TYPE_CONVENTIONAL;
  94        mem->start = PHYSADDR(rd_start);
  95        mem->end = PHYSADDR(rd_end);
  96
  97        printf("   INITRD:          tag:0x%x, type:0X%04lx, start:0X%lx, end:0X%lx\n",
  98               BP_TAG_INITRD, mem->type, mem->start, mem->end);
  99
 100        return bp_tag_next(params);
 101}
 102
 103static struct bp_tag *setup_serial_tag(struct bp_tag *params)
 104{
 105        params->id = BP_TAG_SERIAL_BAUDRATE;
 106        params->size = sizeof(unsigned long);
 107        params->data[0] = gd->baudrate;
 108
 109        printf("   SERIAL_BAUDRATE: tag:0x%04x, size:%u, baudrate:%lu\n",
 110               BP_TAG_SERIAL_BAUDRATE, params->size, params->data[0]);
 111
 112        return bp_tag_next(params);
 113}
 114
 115#ifdef CONFIG_OF_LIBFDT
 116
 117static struct bp_tag *setup_fdt_tag(struct bp_tag *params, void *fdt_start)
 118{
 119        params->id = BP_TAG_FDT;
 120        params->size = sizeof(unsigned long);
 121        params->data[0] = (unsigned long)fdt_start;
 122
 123        printf("   FDT:             tag:0x%04x, size:%u, start:0x%lx\n",
 124               BP_TAG_FDT, params->size, params->data[0]);
 125
 126        return bp_tag_next(params);
 127}
 128
 129#endif
 130
 131/*
 132 * Boot Linux.
 133 */
 134
 135int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
 136{
 137        struct bp_tag *params, *params_start;
 138        ulong initrd_start, initrd_end;
 139        char *commandline = getenv("bootargs");
 140
 141        if (!(flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)))
 142                return 0;
 143
 144        show_boot_progress(15);
 145
 146        if (images->rd_start) {
 147                initrd_start = images->rd_start;
 148                initrd_end = images->rd_end;
 149        } else {
 150                initrd_start = 0;
 151                initrd_end = 0;
 152        }
 153
 154        params_start = (struct bp_tag *)gd->bd->bi_boot_params;
 155        params = params_start;
 156        params = setup_first_tag(params);
 157        params = setup_memory_tag(params);
 158        params = setup_commandline_tag(params, commandline);
 159        params = setup_serial_tag(params);
 160
 161        if (initrd_start)
 162                params = setup_ramdisk_tag(params, initrd_start, initrd_end);
 163
 164#ifdef CONFIG_OF_LIBFDT
 165        if (images->ft_addr)
 166                params = setup_fdt_tag(params, images->ft_addr);
 167#endif
 168
 169        printf("\n");
 170
 171        params = setup_last_tag(params);
 172
 173        show_boot_progress(15);
 174
 175        printf("Transferring Control to Linux @0x%08lx ...\n\n",
 176               (ulong)images->ep);
 177
 178        flush_dcache_range((unsigned long)params_start, (unsigned long)params);
 179
 180        if (flag & BOOTM_STATE_OS_FAKE_GO)
 181                return 0;
 182
 183        /*
 184         * _start() in vmlinux expects boot params in register a2.
 185         * NOTE:
 186         *    Disable/delete your u-boot breakpoints before stepping into linux.
 187         */
 188        asm volatile ("mov      a2, %0\n\t"
 189                      "jx       %1\n\t"
 190                      : : "a" (params_start), "a" (images->ep)
 191                      : "a2");
 192
 193        /* Does not return */
 194
 195        return 1;
 196}
 197
 198