Convert many (but not all) printk(KERN_* to pr_* to simplify the code. We take the opportunity to join some printk lines together so we don't split the message across several lines, and we also add a few levels to some messages which were previously missing them. Tested-by: Andrew Lunn <andrew@lunn.ch> Tested-by: Felipe Balbi <balbi@ti.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
238 lines
6 KiB
C
238 lines
6 KiB
C
/*
|
|
* Tag parsing.
|
|
*
|
|
* Copyright (C) 1995-2001 Russell King
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*/
|
|
|
|
/*
|
|
* This is the traditional way of passing data to the kernel at boot time. Rather
|
|
* than passing a fixed inflexible structure to the kernel, we pass a list
|
|
* of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
|
|
* tag for the list to be recognised (to distinguish the tagged list from
|
|
* a param_struct). The list is terminated with a zero-length tag (this tag
|
|
* is not parsed in any way).
|
|
*/
|
|
|
|
#include <linux/init.h>
|
|
#include <linux/kernel.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/root_dev.h>
|
|
#include <linux/screen_info.h>
|
|
#include <linux/memblock.h>
|
|
|
|
#include <asm/setup.h>
|
|
#include <asm/system_info.h>
|
|
#include <asm/page.h>
|
|
#include <asm/mach/arch.h>
|
|
|
|
#include "atags.h"
|
|
|
|
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
|
|
|
|
#ifndef MEM_SIZE
|
|
#define MEM_SIZE (16*1024*1024)
|
|
#endif
|
|
|
|
static struct {
|
|
struct tag_header hdr1;
|
|
struct tag_core core;
|
|
struct tag_header hdr2;
|
|
struct tag_mem32 mem;
|
|
struct tag_header hdr3;
|
|
} default_tags __initdata = {
|
|
{ tag_size(tag_core), ATAG_CORE },
|
|
{ 1, PAGE_SIZE, 0xff },
|
|
{ tag_size(tag_mem32), ATAG_MEM },
|
|
{ MEM_SIZE },
|
|
{ 0, ATAG_NONE }
|
|
};
|
|
|
|
static int __init parse_tag_core(const struct tag *tag)
|
|
{
|
|
if (tag->hdr.size > 2) {
|
|
if ((tag->u.core.flags & 1) == 0)
|
|
root_mountflags &= ~MS_RDONLY;
|
|
ROOT_DEV = old_decode_dev(tag->u.core.rootdev);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_CORE, parse_tag_core);
|
|
|
|
static int __init parse_tag_mem32(const struct tag *tag)
|
|
{
|
|
return arm_add_memory(tag->u.mem.start, tag->u.mem.size);
|
|
}
|
|
|
|
__tagtable(ATAG_MEM, parse_tag_mem32);
|
|
|
|
#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
|
|
static int __init parse_tag_videotext(const struct tag *tag)
|
|
{
|
|
screen_info.orig_x = tag->u.videotext.x;
|
|
screen_info.orig_y = tag->u.videotext.y;
|
|
screen_info.orig_video_page = tag->u.videotext.video_page;
|
|
screen_info.orig_video_mode = tag->u.videotext.video_mode;
|
|
screen_info.orig_video_cols = tag->u.videotext.video_cols;
|
|
screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx;
|
|
screen_info.orig_video_lines = tag->u.videotext.video_lines;
|
|
screen_info.orig_video_isVGA = tag->u.videotext.video_isvga;
|
|
screen_info.orig_video_points = tag->u.videotext.video_points;
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
|
|
#endif
|
|
|
|
#ifdef CONFIG_BLK_DEV_RAM
|
|
static int __init parse_tag_ramdisk(const struct tag *tag)
|
|
{
|
|
extern int rd_size, rd_image_start, rd_prompt, rd_doload;
|
|
|
|
rd_image_start = tag->u.ramdisk.start;
|
|
rd_doload = (tag->u.ramdisk.flags & 1) == 0;
|
|
rd_prompt = (tag->u.ramdisk.flags & 2) == 0;
|
|
|
|
if (tag->u.ramdisk.size)
|
|
rd_size = tag->u.ramdisk.size;
|
|
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
|
|
#endif
|
|
|
|
static int __init parse_tag_serialnr(const struct tag *tag)
|
|
{
|
|
system_serial_low = tag->u.serialnr.low;
|
|
system_serial_high = tag->u.serialnr.high;
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_SERIAL, parse_tag_serialnr);
|
|
|
|
static int __init parse_tag_revision(const struct tag *tag)
|
|
{
|
|
system_rev = tag->u.revision.rev;
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_REVISION, parse_tag_revision);
|
|
|
|
static int __init parse_tag_cmdline(const struct tag *tag)
|
|
{
|
|
#if defined(CONFIG_CMDLINE_EXTEND)
|
|
strlcat(default_command_line, " ", COMMAND_LINE_SIZE);
|
|
strlcat(default_command_line, tag->u.cmdline.cmdline,
|
|
COMMAND_LINE_SIZE);
|
|
#elif defined(CONFIG_CMDLINE_FORCE)
|
|
pr_warn("Ignoring tag cmdline (using the default kernel command line)\n");
|
|
#else
|
|
strlcpy(default_command_line, tag->u.cmdline.cmdline,
|
|
COMMAND_LINE_SIZE);
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
|
|
|
|
/*
|
|
* Scan the tag table for this tag, and call its parse function.
|
|
* The tag table is built by the linker from all the __tagtable
|
|
* declarations.
|
|
*/
|
|
static int __init parse_tag(const struct tag *tag)
|
|
{
|
|
extern struct tagtable __tagtable_begin, __tagtable_end;
|
|
struct tagtable *t;
|
|
|
|
for (t = &__tagtable_begin; t < &__tagtable_end; t++)
|
|
if (tag->hdr.tag == t->tag) {
|
|
t->parse(tag);
|
|
break;
|
|
}
|
|
|
|
return t < &__tagtable_end;
|
|
}
|
|
|
|
/*
|
|
* Parse all tags in the list, checking both the global and architecture
|
|
* specific tag tables.
|
|
*/
|
|
static void __init parse_tags(const struct tag *t)
|
|
{
|
|
for (; t->hdr.size; t = tag_next(t))
|
|
if (!parse_tag(t))
|
|
pr_warn("Ignoring unrecognised tag 0x%08x\n",
|
|
t->hdr.tag);
|
|
}
|
|
|
|
static void __init squash_mem_tags(struct tag *tag)
|
|
{
|
|
for (; tag->hdr.size; tag = tag_next(tag))
|
|
if (tag->hdr.tag == ATAG_MEM)
|
|
tag->hdr.tag = ATAG_NONE;
|
|
}
|
|
|
|
const struct machine_desc * __init
|
|
setup_machine_tags(phys_addr_t __atags_pointer, unsigned int machine_nr)
|
|
{
|
|
struct tag *tags = (struct tag *)&default_tags;
|
|
const struct machine_desc *mdesc = NULL, *p;
|
|
char *from = default_command_line;
|
|
|
|
default_tags.mem.start = PHYS_OFFSET;
|
|
|
|
/*
|
|
* locate machine in the list of supported machines.
|
|
*/
|
|
for_each_machine_desc(p)
|
|
if (machine_nr == p->nr) {
|
|
pr_info("Machine: %s\n", p->name);
|
|
mdesc = p;
|
|
break;
|
|
}
|
|
|
|
if (!mdesc) {
|
|
early_print("\nError: unrecognized/unsupported machine ID"
|
|
" (r1 = 0x%08x).\n\n", machine_nr);
|
|
dump_machine_table(); /* does not return */
|
|
}
|
|
|
|
if (__atags_pointer)
|
|
tags = phys_to_virt(__atags_pointer);
|
|
else if (mdesc->atag_offset)
|
|
tags = (void *)(PAGE_OFFSET + mdesc->atag_offset);
|
|
|
|
#if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
|
|
/*
|
|
* If we have the old style parameters, convert them to
|
|
* a tag list.
|
|
*/
|
|
if (tags->hdr.tag != ATAG_CORE)
|
|
convert_to_tag_list(tags);
|
|
#endif
|
|
if (tags->hdr.tag != ATAG_CORE) {
|
|
early_print("Warning: Neither atags nor dtb found\n");
|
|
tags = (struct tag *)&default_tags;
|
|
}
|
|
|
|
if (mdesc->fixup)
|
|
mdesc->fixup(tags, &from);
|
|
|
|
if (tags->hdr.tag == ATAG_CORE) {
|
|
if (memblock_phys_mem_size())
|
|
squash_mem_tags(tags);
|
|
save_atags(tags);
|
|
parse_tags(tags);
|
|
}
|
|
|
|
/* parse_early_param needs a boot_command_line */
|
|
strlcpy(boot_command_line, from, COMMAND_LINE_SIZE);
|
|
|
|
return mdesc;
|
|
}
|