/*
* linux/arch/alpha/kernel/setup.c
*
* Copyright (C) 1995 Linus Torvalds
*/
/* 2.3.x bootmem, 1999 Andrea Arcangeli <andrea@suse.de> */
/*
* Bootup setup stuff.
*/
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/a.out.h>
#include <linux/screen_info.h>
#include <linux/delay.h>
#include <linux/mc146818rtc.h>
#include <linux/console.h>
#include <linux/cpu.h>
#include <linux/errno.h>
#include <linux/init.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/bootmem.h>
#include <linux/pci.h>
#include <linux/seq_file.h>
#include <linux/root_dev.h>
#include <linux/initrd.h>
#include <linux/eisa.h>
#include <linux/pfn.h>
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#include <linux/reboot.h>
#endif
#include <linux/notifier.h>
#include <asm/setup.h>
#include <asm/io.h>
extern struct atomic_notifier_head panic_notifier_list;
static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
static struct notifier_block alpha_panic_block = {
alpha_panic_event,
NULL,
INT_MAX /* try to do it first */
};
#include <asm/uaccess.h>
#include <asm/pgtable.h>
#include <asm/system.h>
#include <asm/hwrpb.h>
#include <asm/dma.h>
#include <asm/io.h>
#include <asm/mmu_context.h>
#include <asm/console.h>
#include "proto.h"
#include "pci_impl.h"
struct hwrpb_struct *hwrpb;
EXPORT_SYMBOL(hwrpb);
unsigned long srm_hae;
int alpha_l1i_cacheshape;
int alpha_l1d_cacheshape;
int alpha_l2_cacheshape;
int alpha_l3_cacheshape;
#ifdef CONFIG_VERBOSE_MCHECK
/* 0=minimum, 1=verbose, 2=all */
/* These can be overridden via the command line, ie "verbose_mcheck=2") */
unsigned long alpha_verbose_mcheck = CONFIG_VERBOSE_MCHECK_ON;
#endif
/* Which processor we booted from. */
int boot_cpuid;
/*
* Using SRM callbacks for initial console output. This works from
* setup_arch() time through the end of time_init(), as those places
* are under our (Alpha) control.
* "srmcons" specified in the boot command arguments allows us to
* see kernel messages during the period of time before the true
* console device is "registered" during console_init().
* As of this version (2.5.59), console_init() will call
* disable_early_printk() as the last action before initializing
* the console drivers. That's the last possible time srmcons can be
* unregistered without interfering with console behavior.
*
* By default, OFF; set it with a bootcommand arg of "srmcons" or
* "console=srm". The meaning of these two args is:
* "srmcons" - early callback prints
* "console=srm" - full callback based console, including early prints
*/
int srmcons_output = 0;
/* Enforce a memory size limit; useful for testing. By default, none. */
unsigned long mem_size_limit = 0;
/* Set AGP GART window size (0 means disabled). */
unsigned long alpha_agpgart_size = DEFAULT_AGP_APER_SIZE;
#ifdef CONFIG_ALPHA_GENERIC
struct alpha_machine_vector alpha_mv;
int alpha_using_srm;
EXPORT_SYMBOL(alpha_using_srm);
#endif
static struct alpha_machine_vector *get_sysvec(unsigned long, unsigned long,
unsigned long);
static struct alpha_machine_vector *get_sysvec_byname(const char *);
static void get_sysnames(unsigned long, unsigned long, unsigned long,
char **, char **);
static void determine_cpu_caches (unsigned int);
static char command_line[COMMAND_LINE_SIZE];
/*
* The format of "screen_info" is strange, and due to early
* i386-setup code. This is just enough to make the console
* code think we're on a VGA color display.
*/
struct screen_info screen_info = {
.orig_x = 0,
.orig_y = 25,
.orig_video_cols = 80,
.orig_video_lines = 25,
.orig_video_isVGA = 1,
.orig_video_points = 16
};
EXPORT_SYMBOL(screen_info);
/*
* The direct map I/O window, if any. This should be the same
* for all busses, since it's used by virt_to_bus.
*/
unsigned long __direct_map_base;
unsigned long __direct_map_size;
EXPORT_SYMBOL(__direct_map_base);
EXPORT_SYMBOL(__direct_map_size);
/*
* Declare all of the machine vectors.
*/
/* GCC 2.7.2 (on alpha at least) is lame. It does not support either
__attribute__((weak)) or #pragma weak. Bypass it and talk directly
to the assembler. */
#define WEAK(X) \
extern struct alpha_machine_vector X; \
asm(".weak "#X)
WEAK(alcor_mv);
WEAK(alphabook1_mv);
WEAK(avanti_mv);
WEAK(cabriolet_mv);
WEAK(clipper_mv);
WEAK(dp264_mv);
WEAK(eb164_mv);
WEAK(eb64p_mv);
WEAK(eb66_mv);
WEAK(eb66p_mv);
WEAK(eiger_mv);
WEAK(jensen_mv);
WEAK(lx164_mv);
WEAK(lynx_mv);
WEAK(marvel_ev7_mv);
WEAK(miata_mv);
WEAK(mikasa_mv);
WEAK(mikasa_primo_mv);
WEAK(monet_mv);
WEAK(nautilus_mv);
WEAK(noname_mv);
WEAK(noritake_mv);
WEAK(noritake_primo_mv);
WEAK(p2k_mv);
WEAK(pc164_mv);
WEAK(privateer_mv);
WEAK(rawhide_mv);
WEAK(ruffian_mv);
WEAK(rx164_mv);
WEAK(sable_mv);
WEAK(sable_gamma_mv);
WEAK(shark_mv);
WEAK(sx164_mv);
WEAK(takara_mv);
WEAK(titan_mv);
WEAK(webbrick_mv);
WEAK(wildfire_mv);
WEAK(xl_mv);
WEAK(xlt_mv);
#undef WEAK
/*
* I/O resources inherited from PeeCees. Except for perhaps the
* turbochannel alphas, everyone has these on some sort of SuperIO chip.
*
* ??? If this becomes less standard, move the struct out into the
* machine vector.
*/
static void __init
reserve_std_resources(void)
{
static struct resource standard_io_resources[] = {
{ .name = "rtc", .start = -1, .end = -1 },
{ .name = "dma1", .start = 0x00, .end = 0x1f },
{ .name = "pic1", .start = 0x20, .end = 0x3f },
{ .name = "timer", .start = 0x40, .end = 0x5f },
{ .name = "keyboard", .start = 0x60, .end = 0x6f },
{ .name = "dma page reg", .start = 0x80, .end = 0x8f },
{ .name = "pic2", .start = 0xa0, .end = 0xbf },
{ .name = "dma2", .start = 0xc0, .end = 0xdf },
};
struct resource *io = &ioport_resource;
size_t i;
if (hose_head) {
struct pci_controller *hose;
for (hose = hose_head; hose; hose = hose->next)
if (hose->index == 0) {
io = hose->io_space;
break;
}
}
/* Fix up for the Jensen's queer RTC placement. */
standard_io_resources[0].start = RTC_PORT(0);
standard_io_resources[0].end = RTC_PORT(0) + 0x10;
for (i = 0; i < ARRAY_SIZE(standard_io_resources); ++i)
request_resource(io, standard_io_resources+i);
}
#define PFN_MAX PFN_DOWN(0x80000000)
#define for_each_mem_cluster(memdesc, cluster, i) \
for ((cluster) = (memdesc)->cluster, (i) = 0; \
(i) < (memdesc)->numclusters; (i)++, (cluster)++)
static unsigned long __init
get_mem_size_limit(char *s)
{
unsigned long end = 0;
char *from = s;
end = simple_strtoul(from, &from, 0);
if ( *from == 'K' || *from == 'k' ) {
end = end << 10;
from++;
} else if ( *from == 'M' || *from == 'm' ) {
end = end << 20;
from++;
} else if ( *from == 'G' || *from == 'g' ) {
end = end << 30;
from++;
}
return end >> PAGE_SHIFT; /* Return the PFN of the limit. */
}
#ifdef CONFIG_BLK_DEV_INITRD
void * __init
move_initrd(unsigned long mem_limit)
{
void *start;
unsigned long size;
size = initrd_end - initrd_start;
start = __alloc_bootmem(PAGE_ALIGN(size), PAGE_SIZE, 0);
if (!start || __pa(start) + size > mem_limit) {
initrd_start = initrd_end = 0;
return NULL;
}
memmove(start, (void *)initrd_start, size);
initrd_start = (unsigned long)start;
initrd_end = initrd_start + size;
printk("initrd moved to %p\n", s
|