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