summaryrefslogtreecommitdiffstats
path: root/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c
diff options
context:
space:
mode:
Diffstat (limited to 'uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c')
-rw-r--r--uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c161
1 files changed, 62 insertions, 99 deletions
diff --git a/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c b/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c
index 05af4f1..47e475d 100644
--- a/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c
+++ b/uClinux-2.4.20-uc1/arch/armnommu/kernel/setup.c
@@ -56,6 +56,8 @@ extern void _netarm_led_blink(void);
#endif
extern void paging_init(struct meminfo *, struct machine_desc *desc);
+extern void convert_to_tag_list(struct tag *tags);
+extern void squash_mem_tags(struct tag *tag);
extern void bootmem_init(struct meminfo *);
extern void reboot_setup(char *str);
extern unsigned long long memparse(char *ptr, char **retptr);
@@ -347,6 +349,8 @@ static int __init parse_tag_core(const struct tag *tag)
return 0;
}
+__tagtable(ATAG_CORE, parse_tag_core);
+
static int __init parse_tag_mem32(const struct tag *tag)
{
if (meminfo.nr_banks >= NR_BANKS) {
@@ -363,6 +367,8 @@ static int __init parse_tag_mem32(const struct tag *tag)
return 0;
}
+__tagtable(ATAG_MEM, parse_tag_mem32);
+
static int __init parse_tag_videotext(const struct tag *tag)
{
screen_info.orig_x = tag->u.videotext.x;
@@ -377,6 +383,8 @@ static int __init parse_tag_videotext(const struct tag *tag)
return 0;
}
+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext);
+
static int __init parse_tag_ramdisk(const struct tag *tag)
{
setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
@@ -385,12 +393,16 @@ static int __init parse_tag_ramdisk(const struct tag *tag)
return 0;
}
+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk);
+
static int __init parse_tag_initrd(const struct tag *tag)
{
setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
return 0;
}
+__tagtable(ATAG_INITRD, parse_tag_initrd);
+
static int __init parse_tag_serialnr(const struct tag *tag)
{
system_serial_low = tag->u.serialnr.low;
@@ -398,12 +410,16 @@ static int __init parse_tag_serialnr(const struct tag *tag)
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)
{
strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
@@ -411,110 +427,57 @@ static int __init parse_tag_cmdline(const struct tag *tag)
return 0;
}
-/*
- * This is the core tag table; these are the tags
- * that we recognise for any machine type.
- */
-static const struct tagtable core_tagtable[] __init = {
- { ATAG_CORE, parse_tag_core },
- { ATAG_MEM, parse_tag_mem32 },
- { ATAG_VIDEOTEXT, parse_tag_videotext },
- { ATAG_RAMDISK, parse_tag_ramdisk },
- { ATAG_INITRD, parse_tag_initrd },
- { ATAG_SERIAL, parse_tag_serialnr },
- { ATAG_REVISION, parse_tag_revision },
- { ATAG_CMDLINE, parse_tag_cmdline }
-};
+__tagtable(ATAG_CMDLINE, parse_tag_cmdline);
/*
* Scan one 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 tagtable *tbl, int size, const struct tag *t)
+static int __init parse_tag(const struct tag *tag)
{
- int i;
+ extern struct tagtable __tagtable_begin, __tagtable_end;
+ struct tagtable *t;
- for (i = 0; i < size; i++, tbl++)
- if (t->hdr.tag == tbl->tag) {
- tbl->parse(t);
+ for (t = &__tagtable_begin; t < &__tagtable_end; t++)
+ if (tag->hdr.tag == t->tag) {
+ t->parse(tag);
break;
}
- return i < size;
+ 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 tagtable *tbl, int size, const struct tag *t)
+static void __init parse_tags(const struct tag *t)
{
- /*
- * The tag list is terminated with a zero-sized tag. Size is
- * defined to be in units of 32-bit quantities.
- */
- for (; t->hdr.size; t = (struct tag *)((u32 *)t + t->hdr.size)) {
- if (parse_tag(core_tagtable, ARRAY_SIZE(core_tagtable), t))
- continue;
-
- if (tbl && parse_tag(tbl, size, t))
- continue;
-
- printk(KERN_WARNING
- "Ignoring unrecognised tag 0x%08x\n", t->hdr.tag);
- }
+ for (; t->hdr.size; t = tag_next(t))
+ if (!parse_tag(t))
+ printk(KERN_WARNING
+ "Ignoring unrecognised tag 0x%08x\n",
+ t->hdr.tag);
}
-static void __init parse_params(struct param_struct *params)
-{
- if (params->u1.s.page_size != PAGE_SIZE) {
- printk(KERN_WARNING "Warning: bad configuration page, "
- "trying to continue\n");
- return;
- }
-
- ROOT_DEV = to_kdev_t(params->u1.s.rootdev);
- system_rev = params->u1.s.system_rev;
- system_serial_low = params->u1.s.system_serial_low;
- system_serial_high = params->u1.s.system_serial_high;
-
- if (params->u1.s.mem_fclk_21285 > 0)
- mem_fclk_21285 = params->u1.s.mem_fclk_21285;
-
- setup_ramdisk((params->u1.s.flags & FLAG_RDLOAD) == 0,
- (params->u1.s.flags & FLAG_RDPROMPT) == 0,
- params->u1.s.rd_start,
- params->u1.s.ramdisk_size);
-
- setup_initrd(params->u1.s.initrd_start,
- params->u1.s.initrd_size);
-
- if (!(params->u1.s.flags & FLAG_READONLY))
- root_mountflags &= ~MS_RDONLY;
-
- strncpy(default_command_line, params->commandline, COMMAND_LINE_SIZE);
- default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
-
- if (meminfo.nr_banks == 0) {
- meminfo.nr_banks = 1;
- meminfo.bank[0].start = PHYS_OFFSET;
- meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
- }
-}
-
-
-/*
- * Tell the kernel about any console devices we may have, the user
- * can use bootargs select which one they get. The default will be
- * the console you register first.
- */
-
-
+static struct init_tags {
+ struct tag_header hdr1;
+ struct tag_core core;
+ struct tag_header hdr2;
+ struct tag_mem32 mem;
+ struct tag_header hdr3;
+} init_tags __initdata = {
+ { tag_size(tag_core), ATAG_CORE },
+ { 1, PAGE_SIZE, 0xff },
+ { tag_size(tag_mem32), ATAG_MEM },
+ { MEM_SIZE, PHYS_OFFSET },
+ { 0, ATAG_NONE }
+};
void __init setup_arch(char **cmdline_p)
{
- struct param_struct *params = NULL;
+ struct tag *tags = (struct tag *)&init_tags;
struct machine_desc *mdesc;
char *from = default_command_line;
int bootmap_size;
@@ -533,28 +496,28 @@ void __init setup_arch(char **cmdline_p)
reboot_setup("s");
if (mdesc->param_offset)
- params = (struct param_struct*)
- (phys_to_virt(mdesc->param_offset));
+ tags = phys_to_virt(mdesc->param_offset);
/*
* Do the machine-specific fixups before we parse the
* parameters or tags.
*/
if (mdesc->fixup)
- mdesc->fixup(mdesc, params, &from, &meminfo);
-
- if (params) {
- struct tag *tag = (struct tag *)params;
-
- /*
- * Is the first tag the CORE tag? This differentiates
- * between the tag list and the parameter table.
- */
- if (tag->hdr.tag == ATAG_CORE)
- parse_tags(mdesc->tagtable, mdesc->tagsize, tag);
- else
- parse_params(params);
- }
+ mdesc->fixup(mdesc, (struct param_struct *)tags,
+ &from, &meminfo);
+
+ /*
+ * If we have the old style parameters, convert them to
+ * a tag list.
+ */
+ if (tags->hdr.tag != ATAG_CORE)
+ convert_to_tag_list(tags);
+
+ if (tags->hdr.tag == ATAG_CORE) {
+ if (meminfo.nr_banks != 0)
+ squash_mem_tags(tags);
+ parse_tags(tags);
+ }
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;