patch-2.3.25 linux/arch/arm/kernel/setup.c
Next file: linux/arch/arm/kernel/sys_arm.c
Previous file: linux/arch/arm/kernel/ecard.c
Back to the patch index
Back to the overall index
- Lines: 437
- Date:
Thu Oct 28 10:16:02 1999
- Orig file:
v2.3.24/linux/arch/arm/kernel/setup.c
- Orig date:
Fri Oct 22 13:21:44 1999
diff -u --recursive --new-file v2.3.24/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c
@@ -20,6 +20,7 @@
#include <linux/blk.h>
#include <linux/console.h>
#include <linux/init.h>
+#include <linux/bootmem.h>
#include <asm/elf.h>
#include <asm/hardware.h>
@@ -42,50 +43,74 @@
extern void reboot_setup(char *str, int *ints);
extern void disable_hlt(void);
-
-struct drive_info_struct { char dummy[32]; } drive_info;
-struct screen_info screen_info = {
- orig_video_lines: 30,
- orig_video_cols: 80,
- orig_video_mode: 0,
- orig_video_ega_bx: 0,
- orig_video_isVGA: 1,
- orig_video_points: 8
-};
-
extern int root_mountflags;
-extern int _text, _etext, _edata, _end;
+extern int _stext, _text, _etext, _edata, _end;
-unsigned char aux_device_present;
- char elf_platform[ELF_PLATFORM_SIZE];
-unsigned int elf_hwcap;
-
-/*
- * From head-armv.S
- */
unsigned int processor_id;
unsigned int __machine_arch_type;
unsigned int vram_size;
unsigned int system_rev;
unsigned int system_serial_low;
unsigned int system_serial_high;
-#ifdef MULTI_CPU
-struct processor processor;
-#endif
+unsigned int elf_hwcap;
+
#ifdef CONFIG_ARCH_ACORN
unsigned int memc_ctrl_reg;
unsigned int number_mfm_drives;
#endif
+struct meminfo meminfo;
+
+#ifdef MULTI_CPU
+struct processor processor;
+#endif
+
+struct drive_info_struct { char dummy[32]; } drive_info;
+
+struct screen_info screen_info = {
+ orig_video_lines: 30,
+ orig_video_cols: 80,
+ orig_video_mode: 0,
+ orig_video_ega_bx: 0,
+ orig_video_isVGA: 1,
+ orig_video_points: 8
+};
+
+unsigned char aux_device_present;
+char elf_platform[ELF_PLATFORM_SIZE];
+char saved_command_line[COMMAND_LINE_SIZE];
+
static struct proc_info_item proc_info;
+static char command_line[COMMAND_LINE_SIZE] = { 0, };
+
+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };
#define ENDIANNESS ((char)endian_test.l)
-/*-------------------------------------------------------------------------
- * Early initialisation routines for various configurable items in the
- * kernel. Each one either supplies a setup_ function, or defines this
- * symbol to be empty if not configured.
+/*
+ * Standard memory resources
*/
+static struct resource mem_res[] = {
+ { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY },
+ { "Video RAM", 0, 0, IORESOURCE_MEM },
+ { "Kernel code", 0, 0, IORESOURCE_MEM },
+ { "Kernel data", 0, 0, IORESOURCE_MEM }
+};
+
+#define system_ram mem_res[0]
+#define video_ram mem_res[1]
+#define kernel_code mem_res[2]
+#define kernel_data mem_res[3]
+
+static struct resource io_res[] = {
+ { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY },
+ { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY }
+};
+
+#define lp0 io_res[0]
+#define lp1 io_res[1]
+#define lp2 io_res[2]
static void __init setup_processor(void)
{
@@ -124,55 +149,69 @@
cpu_proc_init();
}
-static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
- char saved_command_line[COMMAND_LINE_SIZE];
+static unsigned long __init memparse(char *ptr, char **retptr)
+{
+ unsigned long ret = simple_strtoul(ptr, retptr, 0);
+ switch (**retptr) {
+ case 'M':
+ case 'm':
+ ret <<= 10;
+ case 'K':
+ case 'k':
+ ret <<= 10;
+ (*retptr)++;
+ default:
+ break;
+ }
+ return ret;
+}
+
+/*
+ * Initial parsing of the command line. We need to pick out the
+ * memory size. We look for mem=size@start, where start and size
+ * are "size[KkMm]"
+ */
static void __init
-setup_mem(char *cmd_line, unsigned long *mem_sz)
+parse_cmdline(char **cmdline_p, char *from)
{
char c = ' ', *to = command_line;
- int len = 0;
-
- if (!*mem_sz)
- *mem_sz = MEM_SIZE;
+ int usermem = 0, len = 0;
for (;;) {
- if (c == ' ') {
- if (cmd_line[0] == 'm' &&
- cmd_line[1] == 'e' &&
- cmd_line[2] == 'm' &&
- cmd_line[3] == '=') {
- *mem_sz = simple_strtoul(cmd_line+4, &cmd_line, 0);
- switch(*cmd_line) {
- case 'M':
- case 'm':
- *mem_sz <<= 10;
- case 'K':
- case 'k':
- *mem_sz <<= 10;
- cmd_line++;
- }
- }
- /* if there are two spaces, remove one */
- if (*cmd_line == ' ') {
- cmd_line++;
- continue;
+ if (c == ' ' && !memcmp(from, "mem=", 4)) {
+ unsigned long size, start;
+
+ if (to != command_line)
+ to -= 1;
+
+ /* If the user specifies memory size, we
+ * blow away any automatically generated
+ * size.
+ */
+ if (usermem == 0) {
+ usermem = 1;
+ meminfo.nr_banks = 0;
}
+
+ start = 0;
+ size = memparse(from + 4, &from);
+ if (*from == '@')
+ start = memparse(from + 1, &from);
+
+ meminfo.bank[meminfo.nr_banks].start = start;
+ meminfo.bank[meminfo.nr_banks].size = size;
+ meminfo.nr_banks += 1;
}
- c = *cmd_line++;
+ c = *from++;
if (!c)
break;
if (COMMAND_LINE_SIZE <= ++len)
break;
*to++ = c;
}
-
*to = '\0';
-
- /* remove trailing spaces */
- while (*--to == ' ' && to != command_line)
- *to = '\0';
+ *cmdline_p = command_line;
}
static void __init
@@ -199,51 +238,90 @@
static void __init setup_initrd(unsigned int start, unsigned int size)
{
#ifdef CONFIG_BLK_DEV_INITRD
- if (start) {
- initrd_start = start;
- initrd_end = start + size;
- } else {
- initrd_start = 0;
- initrd_end = 0;
- }
+ if (start == 0)
+ size = 0;
+ initrd_start = start;
+ initrd_end = start + size;
#endif
}
-static void __init check_initrd(unsigned long mem_end)
+/*
+ * Work out our memory regions. Note that "pfn" is the physical page number
+ * relative to the first physical page, not the physical address itself.
+ */
+static void __init setup_bootmem(void)
{
+ unsigned int end_pfn, bootmem_end;
+ int bank;
+
+ /*
+ * Calculate the end of memory.
+ */
+ for (bank = 0; bank < meminfo.nr_banks; bank++) {
+ if (meminfo.bank[bank].size) {
+ unsigned long end;
+
+ end = meminfo.bank[bank].start +
+ meminfo.bank[bank].size;
+ if (meminfo.end < end)
+ meminfo.end = end;
+ }
+ }
+
+ bootmem_end = __pa(PAGE_ALIGN((unsigned long)&_end));
+ end_pfn = meminfo.end >> PAGE_SHIFT;
+
+ /*
+ * Initialise the boot-time allocator
+ */
+ bootmem_end += init_bootmem(bootmem_end >> PAGE_SHIFT, end_pfn);
+
+ /*
+ * Register all available RAM with the bootmem allocator.
+ * The address is relative to the start of physical memory.
+ */
+ for (bank = 0; bank < meminfo.nr_banks; bank ++)
+ free_bootmem(meminfo.bank[bank].start, meminfo.bank[bank].size);
+
+ /*
+ * reserve the following regions:
+ * physical page 0 - it contains the exception vectors
+ * kernel and the bootmem structure
+ * swapper page directory (if any)
+ * initrd (if any)
+ */
+ reserve_bootmem(0, PAGE_SIZE);
+#ifdef CONFIG_CPU_32
+ reserve_bootmem(__pa(swapper_pg_dir), PTRS_PER_PGD * sizeof(void *));
+#endif
+ reserve_bootmem(__pa(&_stext), bootmem_end - __pa(&_stext));
#ifdef CONFIG_BLK_DEV_INITRD
- if (initrd_end > mem_end) {
+ if (__pa(initrd_end) > (end_pfn << PAGE_SHIFT)) {
printk ("initrd extends beyond end of memory "
- "(0x%08lx > 0x%08lx) - disabling initrd\n",
- initrd_end, mem_end);
+ "(0x%08lx > 0x%08x) - disabling initrd\n",
+ __pa(initrd_end), end_pfn << PAGE_SHIFT);
initrd_start = 0;
}
+
+ if (initrd_start)
+ reserve_bootmem(__pa(initrd_start),
+ initrd_end - initrd_start);
#endif
}
-/*
- * Standard memory resources
- */
-static struct resource system_ram = { "System RAM", 0, 0, IORESOURCE_MEM | IORESOURCE_BUSY };
-static struct resource video_ram = { "Video RAM", 0, 0, IORESOURCE_MEM };
-static struct resource kernel_code = { "Kernel code", 0, 0, IORESOURCE_MEM };
-static struct resource kernel_data = { "Kernel data", 0, 0, IORESOURCE_MEM };
-static struct resource lpt1 = { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY };
-static struct resource lpt2 = { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY };
-static struct resource lpt3 = { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY };
-
-static void __init request_standard_resources(unsigned long end)
+static void __init request_standard_resources(void)
{
kernel_code.start = __virt_to_bus((unsigned long) &_text);
kernel_code.end = __virt_to_bus((unsigned long) &_etext - 1);
kernel_data.start = __virt_to_bus((unsigned long) &_etext);
kernel_data.end = __virt_to_bus((unsigned long) &_edata - 1);
system_ram.start = __virt_to_bus(PAGE_OFFSET);
- system_ram.end = __virt_to_bus(end - 1);
+ system_ram.end = __virt_to_bus(meminfo.end + PAGE_OFFSET - 1);
request_resource(&iomem_resource, &system_ram);
request_resource(&system_ram, &kernel_code);
request_resource(&system_ram, &kernel_data);
+
if (video_ram.start != video_ram.end)
request_resource(&iomem_resource, &video_ram);
@@ -253,17 +331,16 @@
*/
if (machine_is_ebsa110() || machine_is_riscpc() ||
machine_is_netwinder())
- request_resource(&ioport_resource, &lpt1);
+ request_resource(&ioport_resource, &lp0);
if (machine_is_riscpc())
- request_resource(&ioport_resource, &lpt2);
+ request_resource(&ioport_resource, &lp1);
if (machine_is_ebsa110() || machine_is_netwinder())
- request_resource(&ioport_resource, &lpt3);
+ request_resource(&ioport_resource, &lp2);
}
-void __init setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)
+void __init setup_arch(char **cmdline_p)
{
struct param_struct *params = (struct param_struct *)PARAMS_BASE;
- unsigned long memory_end = 0;
char *from = default_command_line;
#if defined(CONFIG_ARCH_ARC)
@@ -296,10 +373,6 @@
case MACH_TYPE_RISCPC:
/* RiscPC can't handle half-word loads and stores */
elf_hwcap &= ~HWCAP_HALF;
- {
- extern void init_dram_banks(struct param_struct *);
- init_dram_banks(params);
- }
switch (params->u1.s.pages_in_vram) {
case 512:
@@ -309,6 +382,17 @@
default:
break;
}
+ {
+ int i;
+
+ for (i = 0; i < 4; i++) {
+ meminfo.bank[i].start = i << 26;
+ meminfo.bank[i].size =
+ params->u1.s.pages_in_bank[i] *
+ params->u1.s.page_size;
+ }
+ meminfo.nr_banks = 4;
+ }
#endif
case MACH_TYPE_ARCHIMEDES:
case MACH_TYPE_A5K:
@@ -347,7 +431,7 @@
*/
reboot_setup("s", NULL);
params = NULL;
- ORIG_VIDEO_LINES = 25;
+ ORIG_VIDEO_LINES = 25;
ORIG_VIDEO_POINTS = 16;
ORIG_Y = 24;
video_ram.start = 0x0a0000;
@@ -393,7 +477,11 @@
}
if (params) {
- memory_end = PAGE_SIZE * params->u1.s.nr_pages;
+ if (meminfo.nr_banks == 0) {
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = 0;
+ meminfo.bank[0].size = params->u1.s.nr_pages << PAGE_SHIFT;
+ }
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;
@@ -413,24 +501,23 @@
from = params->commandline;
}
- /* Save unparsed command line copy for /proc/cmdline */
- memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
- saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
-
- setup_mem(from, &memory_end);
-
- memory_end += PAGE_OFFSET;
+ if (meminfo.nr_banks == 0) {
+ meminfo.nr_banks = 1;
+ meminfo.bank[0].start = 0;
+ meminfo.bank[0].size = MEM_SIZE;
+ }
- *cmdline_p = command_line;
init_mm.start_code = (unsigned long) &_text;
init_mm.end_code = (unsigned long) &_etext;
init_mm.end_data = (unsigned long) &_edata;
init_mm.brk = (unsigned long) &_end;
- *memory_start_p = (unsigned long) &_end;
- *memory_end_p = memory_end;
- request_standard_resources(memory_end);
- check_initrd(memory_end);
+ /* Save unparsed command line copy for /proc/cmdline */
+ memcpy(saved_command_line, from, COMMAND_LINE_SIZE);
+ saved_command_line[COMMAND_LINE_SIZE-1] = '\0';
+ parse_cmdline(cmdline_p, from);
+ setup_bootmem();
+ request_standard_resources();
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)