4 * Copyright (C) 1995-2001 Russell King
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
12 * This is the traditional way of passing data to the kernel at boot time. Rather
13 * than passing a fixed inflexible structure to the kernel, we pass a list
14 * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE
15 * tag for the list to be recognised (to distinguish the tagged list from
16 * a param_struct). The list is terminated with a zero-length tag (this tag
17 * is not parsed in any way).
20 #include <linux/init.h>
21 #include <linux/kernel.h>
23 #include <linux/root_dev.h>
24 #include <linux/screen_info.h>
25 #include <linux/memblock.h>
27 #include <asm/setup.h>
28 #include <asm/system_info.h>
30 #include <asm/mach/arch.h>
34 static char default_command_line
[COMMAND_LINE_SIZE
] __initdata
= CONFIG_CMDLINE
;
37 #define MEM_SIZE (16*1024*1024)
41 struct tag_header hdr1
;
43 struct tag_header hdr2
;
45 struct tag_header hdr3
;
46 } default_tags __initdata
= {
47 { tag_size(tag_core
), ATAG_CORE
},
48 { 1, PAGE_SIZE
, 0xff },
49 { tag_size(tag_mem32
), ATAG_MEM
},
54 static int __init
parse_tag_core(const struct tag
*tag
)
56 if (tag
->hdr
.size
> 2) {
57 if ((tag
->u
.core
.flags
& 1) == 0)
58 root_mountflags
&= ~MS_RDONLY
;
59 ROOT_DEV
= old_decode_dev(tag
->u
.core
.rootdev
);
64 __tagtable(ATAG_CORE
, parse_tag_core
);
66 static int __init
parse_tag_mem32(const struct tag
*tag
)
68 return arm_add_memory(tag
->u
.mem
.start
, tag
->u
.mem
.size
);
71 __tagtable(ATAG_MEM
, parse_tag_mem32
);
73 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE)
74 static int __init
parse_tag_videotext(const struct tag
*tag
)
76 screen_info
.orig_x
= tag
->u
.videotext
.x
;
77 screen_info
.orig_y
= tag
->u
.videotext
.y
;
78 screen_info
.orig_video_page
= tag
->u
.videotext
.video_page
;
79 screen_info
.orig_video_mode
= tag
->u
.videotext
.video_mode
;
80 screen_info
.orig_video_cols
= tag
->u
.videotext
.video_cols
;
81 screen_info
.orig_video_ega_bx
= tag
->u
.videotext
.video_ega_bx
;
82 screen_info
.orig_video_lines
= tag
->u
.videotext
.video_lines
;
83 screen_info
.orig_video_isVGA
= tag
->u
.videotext
.video_isvga
;
84 screen_info
.orig_video_points
= tag
->u
.videotext
.video_points
;
88 __tagtable(ATAG_VIDEOTEXT
, parse_tag_videotext
);
91 #ifdef CONFIG_BLK_DEV_RAM
92 static int __init
parse_tag_ramdisk(const struct tag
*tag
)
94 extern int rd_size
, rd_image_start
, rd_prompt
, rd_doload
;
96 rd_image_start
= tag
->u
.ramdisk
.start
;
97 rd_doload
= (tag
->u
.ramdisk
.flags
& 1) == 0;
98 rd_prompt
= (tag
->u
.ramdisk
.flags
& 2) == 0;
100 if (tag
->u
.ramdisk
.size
)
101 rd_size
= tag
->u
.ramdisk
.size
;
106 __tagtable(ATAG_RAMDISK
, parse_tag_ramdisk
);
109 static int __init
parse_tag_serialnr(const struct tag
*tag
)
111 system_serial_low
= tag
->u
.serialnr
.low
;
112 system_serial_high
= tag
->u
.serialnr
.high
;
116 __tagtable(ATAG_SERIAL
, parse_tag_serialnr
);
118 static int __init
parse_tag_revision(const struct tag
*tag
)
120 system_rev
= tag
->u
.revision
.rev
;
124 __tagtable(ATAG_REVISION
, parse_tag_revision
);
126 static int __init
parse_tag_cmdline(const struct tag
*tag
)
128 #if defined(CONFIG_CMDLINE_EXTEND)
129 strlcat(default_command_line
, " ", COMMAND_LINE_SIZE
);
130 strlcat(default_command_line
, tag
->u
.cmdline
.cmdline
,
132 #elif defined(CONFIG_CMDLINE_FORCE)
133 pr_warning("Ignoring tag cmdline (using the default kernel command line)\n");
135 strlcpy(default_command_line
, tag
->u
.cmdline
.cmdline
,
141 __tagtable(ATAG_CMDLINE
, parse_tag_cmdline
);
144 * Scan the tag table for this tag, and call its parse function.
145 * The tag table is built by the linker from all the __tagtable
148 static int __init
parse_tag(const struct tag
*tag
)
150 extern struct tagtable __tagtable_begin
, __tagtable_end
;
153 for (t
= &__tagtable_begin
; t
< &__tagtable_end
; t
++)
154 if (tag
->hdr
.tag
== t
->tag
) {
159 return t
< &__tagtable_end
;
163 * Parse all tags in the list, checking both the global and architecture
164 * specific tag tables.
166 static void __init
parse_tags(const struct tag
*t
)
168 for (; t
->hdr
.size
; t
= tag_next(t
))
171 "Ignoring unrecognised tag 0x%08x\n",
175 static void __init
squash_mem_tags(struct tag
*tag
)
177 for (; tag
->hdr
.size
; tag
= tag_next(tag
))
178 if (tag
->hdr
.tag
== ATAG_MEM
)
179 tag
->hdr
.tag
= ATAG_NONE
;
182 const struct machine_desc
* __init
183 setup_machine_tags(phys_addr_t __atags_pointer
, unsigned int machine_nr
)
185 struct tag
*tags
= (struct tag
*)&default_tags
;
186 const struct machine_desc
*mdesc
= NULL
, *p
;
187 char *from
= default_command_line
;
189 default_tags
.mem
.start
= PHYS_OFFSET
;
192 * locate machine in the list of supported machines.
194 for_each_machine_desc(p
)
195 if (machine_nr
== p
->nr
) {
196 printk("Machine: %s\n", p
->name
);
202 early_print("\nError: unrecognized/unsupported machine ID"
203 " (r1 = 0x%08x).\n\n", machine_nr
);
204 dump_machine_table(); /* does not return */
208 tags
= phys_to_virt(__atags_pointer
);
209 else if (mdesc
->atag_offset
)
210 tags
= (void *)(PAGE_OFFSET
+ mdesc
->atag_offset
);
212 #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)
214 * If we have the old style parameters, convert them to
217 if (tags
->hdr
.tag
!= ATAG_CORE
)
218 convert_to_tag_list(tags
);
220 if (tags
->hdr
.tag
!= ATAG_CORE
) {
221 early_print("Warning: Neither atags nor dtb found\n");
222 tags
= (struct tag
*)&default_tags
;
226 mdesc
->fixup(tags
, &from
);
228 if (tags
->hdr
.tag
== ATAG_CORE
) {
229 if (memblock_phys_mem_size())
230 squash_mem_tags(tags
);
235 /* parse_early_param needs a boot_command_line */
236 strlcpy(boot_command_line
, from
, COMMAND_LINE_SIZE
);