patch-2.4.4 linux/arch/arm/kernel/setup.c
Next file: linux/arch/arm/kernel/time-acorn.c
Previous file: linux/arch/arm/kernel/semaphore.c
Back to the patch index
Back to the overall index
- Lines: 336
- Date:
Fri Apr 27 14:10:31 2001
- Orig file:
v2.4.3/linux/arch/arm/kernel/setup.c
- Orig date:
Mon Sep 18 15:15:25 2000
diff -u --recursive --new-file v2.4.3/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
@@ -26,6 +26,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
+#include <asm/mach/irq.h>
#ifndef MEM_SIZE
#define MEM_SIZE (16*1024*1024)
@@ -35,10 +36,21 @@
#define CONFIG_CMDLINE ""
#endif
+#if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)
+char fpe_type[8];
+
+static int __init fpe_setup(char *line)
+{
+ memcpy(fpe_type, line, 8);
+ return 1;
+}
+
+__setup("fpe=", fpe_setup);
+#endif
+
extern void paging_init(struct meminfo *, struct machine_desc *desc);
extern void bootmem_init(struct meminfo *);
extern void reboot_setup(char *str);
-extern void disable_hlt(void);
extern unsigned long memparse(char *ptr, char **retptr);
extern int root_mountflags;
extern int _stext, _text, _etext, _edata, _end;
@@ -71,9 +83,10 @@
char elf_platform[ELF_PLATFORM_SIZE];
char saved_command_line[COMMAND_LINE_SIZE];
+static struct meminfo meminfo __initdata = { 0, };
static struct proc_info_item proc_info;
static const char *machine_name;
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
+static char command_line[COMMAND_LINE_SIZE];
static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
@@ -228,7 +241,7 @@
setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz)
{
#ifdef CONFIG_BLK_DEV_RAM
- extern int rd_doload, rd_prompt, rd_image_start, rd_size;
+ extern int rd_size;
rd_image_start = image_start;
rd_prompt = prompt;
@@ -306,71 +319,222 @@
request_resource(&ioport_resource, &lp2);
}
+/*
+ * Tag parsing.
+ *
+ * This is the new 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).
+ */
+static int __init parse_tag_core(const struct tag *tag)
+{
+ if ((tag->u.core.flags & 1) == 0)
+ root_mountflags &= ~MS_RDONLY;
+ ROOT_DEV = to_kdev_t(tag->u.core.rootdev);
+ return 0;
+}
+
+static int __init parse_tag_mem32(const struct tag *tag)
+{
+ if (meminfo.nr_banks >= NR_BANKS) {
+ printk(KERN_WARNING
+ "Ignoring memory bank 0x%08x size %dKB\n",
+ tag->u.mem.start, tag->u.mem.size / 1024);
+ return -EINVAL;
+ }
+ meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start;
+ meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size;
+ meminfo.bank[meminfo.nr_banks].node = 0;
+ meminfo.nr_banks += 1;
+
+ return 0;
+}
+
+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;
+}
+
+static int __init parse_tag_ramdisk(const struct tag *tag)
+{
+ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0,
+ (tag->u.ramdisk.flags & 2) == 0,
+ tag->u.ramdisk.start, tag->u.ramdisk.size);
+ return 0;
+}
+
+static int __init parse_tag_initrd(const struct tag *tag)
+{
+ setup_initrd(tag->u.initrd.start, tag->u.initrd.size);
+ return 0;
+}
+
+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;
+}
+
+static int __init parse_tag_revision(const struct tag *tag)
+{
+ system_rev = tag->u.revision.rev;
+ return 0;
+}
+
+static int __init parse_tag_cmdline(const struct tag *tag)
+{
+ strncpy(default_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
+ default_command_line[COMMAND_LINE_SIZE - 1] = '\0';
+ 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 }
+};
+
+/*
+ * Scan one tag table for this tag, and call its parse function.
+ */
+static int __init
+parse_tag(const struct tagtable *tbl, int size, const struct tag *t)
+{
+ int i;
+
+ for (i = 0; i < size; i++, tbl++)
+ if (t->hdr.tag == tbl->tag) {
+ tbl->parse(t);
+ break;
+ }
+
+ return i < size;
+}
+
+/*
+ * 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)
+{
+ /*
+ * 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);
+ }
+}
+
+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;
+ }
+}
+
void __init setup_arch(char **cmdline_p)
{
struct param_struct *params = NULL;
struct machine_desc *mdesc;
- struct meminfo meminfo;
char *from = default_command_line;
- memset(&meminfo, 0, sizeof(meminfo));
-
- setup_processor();
-
ROOT_DEV = MKDEV(0, 255);
+ setup_processor();
mdesc = setup_architecture(machine_arch_type);
machine_name = mdesc->name;
- if (mdesc->broken_hlt)
- disable_hlt();
-
if (mdesc->soft_reboot)
reboot_setup("s");
if (mdesc->param_offset)
params = 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 && params->u1.s.page_size != PAGE_SIZE) {
- printk(KERN_WARNING "Warning: bad configuration page, "
- "trying to continue\n");
- params = NULL;
- }
-
if (params) {
- 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;
+ struct tag *tag = (struct tag *)params;
- from = params->commandline;
+ /*
+ * 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);
}
if (meminfo.nr_banks == 0) {
meminfo.nr_banks = 1;
meminfo.bank[0].start = PHYS_OFFSET;
- meminfo.bank[0].node = 0;
- if (params)
- meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
- else
- meminfo.bank[0].size = MEM_SIZE;
+ meminfo.bank[0].size = MEM_SIZE;
}
init_mm.start_code = (unsigned long) &_text;
@@ -385,6 +549,11 @@
paging_init(&meminfo, mdesc);
request_standard_resources(&meminfo, mdesc);
+ /*
+ * Set up various architecture-specific pointers
+ */
+ init_arch_irq = mdesc->init_irq;
+
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
@@ -403,8 +572,8 @@
(int)processor_id & 15, elf_platform);
p += sprintf(p, "BogoMIPS\t: %lu.%02lu\n",
- (loops_per_sec+2500) / 500000,
- ((loops_per_sec+2500) / 5000) % 100);
+ loops_per_jiffy / (500000/HZ),
+ (loops_per_jiffy / (5000/HZ)) % 100);
p += sprintf(p, "Hardware\t: %s\n", machine_name);
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)