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