patch-2.1.116 linux/arch/alpha/kernel/setup.c
Next file: linux/arch/alpha/kernel/smp.c
Previous file: linux/arch/alpha/kernel/pyxis.c
Back to the patch index
Back to the overall index
- Lines: 910
- Date:
Sun Aug 9 12:10:58 1998
- Orig file:
v2.1.115/linux/arch/alpha/kernel/setup.c
- Orig date:
Thu Aug 6 14:06:28 1998
diff -u --recursive --new-file v2.1.115/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c
@@ -5,10 +5,9 @@
*/
/*
- * bootup setup stuff..
+ * Bootup setup stuff.
*/
-#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
@@ -24,6 +23,9 @@
#include <linux/ioport.h>
#include <linux/mc146818rtc.h>
#include <linux/console.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/string.h>
#ifdef CONFIG_RTC
#include <linux/timex.h>
@@ -36,8 +38,8 @@
#include <asm/dma.h>
#include <asm/io.h>
-extern void setup_smp(void);
-extern char *smp_info(void);
+
+#include "proto.h"
#if 1
# define DBG_SRM(args) printk args
@@ -45,19 +47,23 @@
# define DBG_SRM(args)
#endif
-struct hae hae = {
- 0,
- (unsigned long*) HAE_ADDRESS
-};
-
-#ifdef CONFIG_ALPHA_SRM_SETUP
+struct hwrpb_struct *hwrpb;
unsigned long srm_hae;
-#endif
-struct hwrpb_struct *hwrpb;
+#ifdef CONFIG_ALPHA_GENERIC
+struct alpha_machine_vector alpha_mv;
+int alpha_using_srm, alpha_use_srm_setup;
+#endif
unsigned char aux_device_present = 0xaa;
+#define N(a) (sizeof(a)/sizeof(a[0]))
+
+static unsigned long find_end_memory(void);
+static struct alpha_machine_vector *get_sysvec(long, long, long);
+static struct alpha_machine_vector *get_sysvec_byname(const char *);
+static void get_sysnames(long, long, char **, char **);
+
/*
* This is setup by the secondary bootstrap loader. Because
* the zero page is zeroed out as soon as the vm system is
@@ -68,161 +74,241 @@
#define COMMAND_LINE ((char*)(PARAM + 0x0000))
#define COMMAND_LINE_SIZE 256
-static char command_line[COMMAND_LINE_SIZE] = { 0, };
- char saved_command_line[COMMAND_LINE_SIZE];
+static char command_line[COMMAND_LINE_SIZE];
+char saved_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 = {
-#if defined(CONFIG_ALPHA_BOOK1)
- /* the AlphaBook1 has LCD video fixed at 800x600, 37 rows and 100 cols */
- 0, 37, /* orig-x, orig-y */
- { 0, 0 }, /* unused */
- 0, /* orig-video-page */
- 0, /* orig-video-mode */
- 100, /* orig-video-cols */
- 0,0,0, /* ega_ax, ega_bx, ega_cx */
- 37, /* orig-video-lines */
- 1, /* orig-video-isVGA */
- 16 /* orig-video-points */
-#else
- 0, 25, /* orig-x, orig-y */
- 0, /* unused */
- 0, /* orig-video-page */
- 0, /* orig-video-mode */
- 80, /* orig-video-cols */
- 0,0,0, /* ega_ax, ega_bx, ega_cx */
- 25, /* orig-video-lines */
- 1, /* orig-video-isVGA */
- 16 /* orig-video-points */
-#endif
+ orig_x: 0,
+ orig_y: 25,
+ orig_video_cols: 80,
+ orig_video_lines: 25,
+ orig_video_isVGA: 1,
+ orig_video_points: 16
};
+
/*
* Initialize Programmable Interval Timers with standard values. Some
* drivers depend on them being initialized (e.g., joystick driver).
*/
-static void init_pit (void)
+
+/* It is (normally) only counter 1 that presents config problems, so
+ provide this support function to do the rest of the job. */
+
+void inline
+init_pit_rest(void)
{
#if 0
- /*
- * Leave refresh timer alone---nobody should depend on
- * a particular value anyway.
- */
- outb(0x54, 0x43); /* counter 1: refresh timer */
- outb(0x18, 0x41);
-#endif
-
-#ifdef CONFIG_RTC /* setup interval timer if /dev/rtc is being used */
- outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
- outb(LATCH & 0xff, 0x40); /* LSB */
- outb(LATCH >> 8, 0x40); /* MSB */
- request_region(0x40, 0x20, "timer"); /* reserve pit */
-#else /* RTC */
-#if !defined(CONFIG_ALPHA_RUFFIAN)
- /* Ruffian depends on the system timer established in MILO!! */
- outb(0x36, 0x43); /* counter 0: system timer */
- outb(0x00, 0x40);
- outb(0x00, 0x40);
-#endif /* RUFFIAN */
- request_region(0x70, 0x10, "timer"); /* reserve rtc */
-#endif /* RTC */
-
- outb(0xb6, 0x43); /* counter 2: speaker */
- outb(0x31, 0x42);
- outb(0x13, 0x42);
+ /* Leave refresh timer alone---nobody should depend on a
+ particular value anyway. */
+ outb(0x54, 0x43); /* counter 1: refresh timer */
+ outb(0x18, 0x41);
+#endif
+
+ outb(0xb6, 0x43); /* counter 2: speaker */
+ outb(0x31, 0x42);
+ outb(0x13, 0x42);
+
+ if ((CMOS_READ(RTC_FREQ_SELECT) & 0x3f) != 0x26) {
+ printk("Setting RTC_FREQ to 1024 Hz\n");
+ CMOS_WRITE(0x26, RTC_FREQ_SELECT);
+ }
}
-static unsigned long find_end_memory(void)
+#ifdef CONFIG_RTC
+static inline void
+rtc_init_pit (void)
{
- int i;
- unsigned long high = 0;
- struct memclust_struct * cluster;
- struct memdesc_struct * memdesc;
+ /* Setup interval timer if /dev/rtc is being used */
+ outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */
+ outb(LATCH & 0xff, 0x40); /* LSB */
+ outb(LATCH >> 8, 0x40); /* MSB */
+ request_region(0x40, 0x20, "timer"); /* reserve pit */
- memdesc = (struct memdesc_struct *)
- (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
- cluster = memdesc->cluster;
- for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
- unsigned long tmp;
- tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
- if (tmp > high)
- high = tmp;
- }
- /* round it up to an even number of pages.. */
- high = (high + PAGE_SIZE) & (PAGE_MASK*2);
- return PAGE_OFFSET + high;
+ init_pit_rest();
}
+#endif
-void setup_arch(char **cmdline_p,
- unsigned long * memory_start_p, unsigned long * memory_end_p)
+void
+generic_init_pit (void)
{
- extern int _end;
+ outb(0x36, 0x43); /* counter 0: system timer */
+ outb(0x00, 0x40);
+ outb(0x00, 0x40);
+ request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */
- init_pit();
+ init_pit_rest();
+}
- if ((CMOS_READ(RTC_FREQ_SELECT) & 0x3f) != 0x26) {
- printk("setup_arch: setting RTC_FREQ to 1024/sec\n");
- CMOS_WRITE(0x26, RTC_FREQ_SELECT);
- }
+/* This probably isn't Right, but it is what the old code did. */
+#if defined(CONFIG_RTC)
+# define init_pit rtc_init_pit
+#else
+# define init_pit alpha_mv.init_pit
+#endif
+
+
+/*
+ * Declare all of the machine vectors.
+ */
+
+extern struct alpha_machine_vector alcor_mv;
+extern struct alpha_machine_vector alphabook1_mv;
+extern struct alpha_machine_vector avanti_mv;
+extern struct alpha_machine_vector cabriolet_mv;
+extern struct alpha_machine_vector dp264_mv;
+extern struct alpha_machine_vector eb164_mv;
+extern struct alpha_machine_vector eb64p_mv;
+extern struct alpha_machine_vector eb66_mv;
+extern struct alpha_machine_vector eb66p_mv;
+extern struct alpha_machine_vector jensen_mv;
+extern struct alpha_machine_vector lx164_mv;
+extern struct alpha_machine_vector miata_mv;
+extern struct alpha_machine_vector mikasa_mv;
+extern struct alpha_machine_vector mikasa_primo_mv;
+extern struct alpha_machine_vector noname_mv;
+extern struct alpha_machine_vector noritake_mv;
+extern struct alpha_machine_vector noritake_primo_mv;
+extern struct alpha_machine_vector p2k_mv;
+extern struct alpha_machine_vector pc164_mv;
+extern struct alpha_machine_vector rawhide_mv;
+extern struct alpha_machine_vector ruffian_mv;
+extern struct alpha_machine_vector sable_mv;
+extern struct alpha_machine_vector sable_gamma_mv;
+extern struct alpha_machine_vector sx164_mv;
+extern struct alpha_machine_vector takara_mv;
+extern struct alpha_machine_vector xl_mv;
+extern struct alpha_machine_vector xlt_mv;
+
+
+void __init
+setup_arch(char **cmdline_p, unsigned long * memory_start_p,
+ unsigned long * memory_end_p)
+{
+ extern char _end[];
+
+ struct alpha_machine_vector *vec = NULL;
+ struct percpu_struct *cpu;
+ char *type_name, *var_name, *p;
hwrpb = (struct hwrpb_struct*)(IDENT_ADDR + INIT_HWRPB->phys_addr);
-#if !defined(CONFIG_ALPHA_TSUNAMI)
-#ifdef CONFIG_ALPHA_SRM_SETUP
- srm_hae = *hae.reg; /* save SRM setting for restoration */
- DBG_SRM(("setup_arch: old HAE base: 0x%016lx\n", srm_hae));
-#endif /* SRM_SETUP */
- set_hae(hae.cache); /* sync HAE register w/hae_cache */
-#endif /* !TSUNAMI */
-
- wrmces(0x7); /* reset enable correctable error reports */
-
- ROOT_DEV = to_kdev_t(0x0802); /* sda2 */
- command_line[COMMAND_LINE_SIZE - 1] = '\0';
-
- /* Hack for Jensen... since we're restricted to 8 or 16
- * chars for boot flags depending on the boot mode,
- * we need some shorthand. This should do for
- * installation. Later we'll add other abbreviations
- * as well...
+ /*
+ * Locate the command line.
*/
+
+ /* Hack for Jensen... since we're restricted to 8 or 16 chars for
+ boot flags depending on the boot mode, we need some shorthand.
+ This should do for installation. Later we'll add other
+ abbreviations as well... */
if (strcmp(COMMAND_LINE, "INSTALL") == 0) {
strcpy(command_line, "root=/dev/fd0 load_ramdisk=1");
- strcpy(saved_command_line, command_line);
} else {
- strcpy(command_line, COMMAND_LINE);
- strcpy(saved_command_line, COMMAND_LINE);
+ strncpy(command_line, COMMAND_LINE, sizeof command_line);
+ command_line[sizeof(command_line)-1] = 0;
}
- printk("Command line: %s\n", command_line);
-
+ strcpy(saved_command_line, command_line);
*cmdline_p = command_line;
- *memory_start_p = (unsigned long) &_end;
- *memory_end_p = find_end_memory();
-#if defined(CONFIG_ALPHA_LCA)
- *memory_start_p = lca_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_APECS)
- *memory_start_p = apecs_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_CIA)
- *memory_start_p = cia_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_PYXIS)
- *memory_start_p = pyxis_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_T2)
- *memory_start_p = t2_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_TSUNAMI)
- *memory_start_p = tsunami_init(*memory_start_p, *memory_end_p);
-#elif defined(CONFIG_ALPHA_MCPCIA)
- *memory_start_p = mcpcia_init(*memory_start_p, *memory_end_p);
+ /*
+ * Process command-line arguments.
+ */
+
+ for (p = strtok(command_line, " \t"); p ; p = strtok(NULL, " \t")) {
+#ifndef alpha_use_srm_setup
+ /* Allow a command-line option to respect the
+ SRM's configuration. */
+ if (strncmp(p, "srm_setup=", 10) == 0) {
+ alpha_use_srm_setup = (p[10] != '0');
+ continue;
+ }
#endif
-#ifdef __SMP__
- setup_smp();
+ if (strncmp(p, "alpha_mv=", 9) == 0) {
+ vec = get_sysvec_byname(p+9);
+ continue;
+ }
+ }
+
+ /* Replace the command line, not that we've killed it with strtok. */
+ strcpy(command_line, saved_command_line);
+
+ /*
+ * Indentify and reconfigure for the current system.
+ */
+
+ get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
+ &type_name, &var_name);
+ if (*var_name == '0')
+ var_name = "";
+
+ if (!vec) {
+ cpu = (struct percpu_struct*)
+ ((char*)hwrpb + hwrpb->processor_offset);
+ vec = get_sysvec(hwrpb->sys_type, hwrpb->sys_variation,
+ cpu->type);
+ }
+
+#ifdef CONFIG_ALPHA_GENERIC
+ if (!vec) {
+ panic("Unsupported system type: %s%s%s (%ld %ld)\n",
+ type_name, (*var_name ? " variation " : ""), var_name,
+ hwrpb->sys_type, hwrpb->sys_variation);
+ }
+ alpha_mv = *vec;
+
+ /* Assume that we've booted from SRM if we havn't booted from MILO.
+ Detect the later by looking for "MILO" in the system serial nr. */
+ alpha_using_srm = strncmp((const char *)hwrpb->ssn, "MILO", 4) != 0;
+#else
+ /* Once we're sure we can reliably identify systems, we should
+ simply panic as we do above. */
+ if (vec != &alpha_mv) {
+ printk("WARNING: Not configured for system type: %s%s%s "
+ "(%ld %ld)\nContinuing with trepidation...\n",
+ type_name, (*var_name ? " variation " : ""), var_name,
+ hwrpb->sys_type, hwrpb->sys_variation);
+ }
#endif
+ /*
+ * Sync with the HAE
+ */
+
+ /* Save the SRM's current value for restoration. */
+ srm_hae = *alpha_mv.hae_register;
+ __set_hae(alpha_mv.hae_cache);
+
+ /* Reset enable correctable error reports. */
+ wrmces(0x7);
+
+ /* Find our memory. */
+ *memory_end_p = find_end_memory();
+ *memory_start_p = (unsigned long) _end;
+
+ /* Initialize the machine. Usually has to do with setting up
+ DMA windows and the like. */
+ if (alpha_mv.init_arch)
+ alpha_mv.init_arch(memory_start_p, memory_end_p);
+
+ /* Initialize the timers. */
+ init_pit();
+
+ /* Default root filesystem to sda2. */
+ ROOT_DEV = to_kdev_t(0x0802);
+
+ /*
+ * Give us a default console. TGA users will see nothing until
+ * chr_dev_init is called, rather late in the boot sequence.
+ */
+
#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
@@ -230,81 +316,284 @@
conswitchp = &dummy_con;
#endif
#endif
-}
+ /* Delayed so that we've initialized the machine first. */
+ printk("Booting on %s%s%s using machine vector %s\n",
+ type_name, (*var_name ? " variation " : ""),
+ var_name, alpha_mv.vector_name);
+ printk("Command line: %s\n", command_line);
-#define N(a) (sizeof(a)/sizeof(a[0]))
+ /*
+ * Check ASN in HWRPB for validity, report if bad.
+ * FIXME: how was this failing? Should we trust it instead,
+ * and copy the value into alpha_mv.max_asn?
+ */
+
+ if (hwrpb->max_asn != MAX_ASN) {
+ printk("Max ASN from HWRPB is bad (0x%lx)\n", hwrpb->max_asn);
+ }
-/* A change was made to the HWRPB via an ECO and the following code tracks
- * a part of the ECO. In HWRPB versions less than 5, the ECO was not
- * implemented in the console firmware. If it's revision 5 or greater we can
- * get the name of the platform as an ASCII string from the HWRPB. That's what
- * this function does. It checks the revision level and if the string is in
- * the HWRPB it returns the address of the string--a pointer to the name of the
- * platform.
- *
- * Returns:
- * - Pointer to a ASCII string if it's in the HWRPB
- * - Pointer to a blank string if the data is not in the HWRPB.
- */
-static char *
-platform_string(void)
+ /*
+ * Identify the flock of penguins.
+ */
+
+#ifdef __SMP__
+ setup_smp();
+#endif
+}
+
+static unsigned long __init
+find_end_memory(void)
{
- struct dsr_struct *dsr;
- static char unk_system_string[] = "N/A";
+ int i;
+ unsigned long high = 0;
+ struct memclust_struct * cluster;
+ struct memdesc_struct * memdesc;
- /* Go to the console for the string pointer.
- * If the rpb_vers is not 5 or greater the rpb
- * is old and does not have this data in it.
- */
- if (hwrpb->revision < 5)
- return (unk_system_string);
- else {
- /* The Dynamic System Recognition struct
- * has the system platform name starting
- * after the character count of the string.
- */
- dsr = ((struct dsr_struct *)
- ((char *)hwrpb + hwrpb->dsr_offset));
- return ((char *)dsr + (dsr->sysname_off +
- sizeof(long)));
- }
+ memdesc = (struct memdesc_struct *)
+ (INIT_HWRPB->mddt_offset + (unsigned long) INIT_HWRPB);
+ cluster = memdesc->cluster;
+
+ for (i = memdesc->numclusters ; i > 0; i--, cluster++) {
+ unsigned long tmp;
+ tmp = (cluster->start_pfn + cluster->numpages) << PAGE_SHIFT;
+ if (tmp > high)
+ high = tmp;
+ }
+
+ /* Round it up to an even number of pages. */
+ high = (high + PAGE_SIZE) & (PAGE_MASK*2);
+ return PAGE_OFFSET + high;
}
-static void
-get_sysnames(long type, long variation,
- char **type_name, char **variation_name)
+
+static char sys_unknown[] = "Unknown";
+static char systype_names[][16] = {
+ "0",
+ "ADU", "Cobra", "Ruby", "Flamingo", "Mannequin", "Jensen",
+ "Pelican", "Morgan", "Sable", "Medulla", "Noname",
+ "Turbolaser", "Avanti", "Mustang", "Alcor", "Tradewind",
+ "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
+ "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
+ "Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
+ "Tsunami", "Wildfire", "CUSCO"
+};
+
+static char unofficial_names[][8] = {"100", "Ruffian"};
+
+static char eb164_names[][8] = {"EB164", "PC164", "LX164", "SX164"};
+static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3};
+
+static char alcor_names[][16] = {"Alcor", "Maverick", "Bret"};
+static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
+
+static char eb64p_names[][16] = {"EB64+", "Cabriolet", "AlphaPCI64"};
+static int eb64p_indices[] = {0,0,1,2};
+
+static char eb66_names[][8] = {"EB66", "EB66+"};
+static int eb66_indices[] = {0,0,1};
+
+static char rawhide_names[][16] = {
+ "Dodge", "Wrangler", "Durango", "Tincup", "DaVinci"
+};
+static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
+
+
+static struct alpha_machine_vector * __init
+get_sysvec(long type, long variation, long cpu)
{
- static char *sys_unknown = "Unknown";
- static char *systype_names[] = {
- "0",
- "ADU", "Cobra", "Ruby", "Flamingo", "Mannequin", "Jensen",
- "Pelican", "Morgan", "Sable", "Medulla", "Noname",
- "Turbolaser", "Avanti", "Mustang", "Alcor", "Tradewind",
- "Mikasa", "EB64", "EB66", "EB64+", "AlphaBook1",
- "Rawhide", "K2", "Lynx", "XL", "EB164", "Noritake",
- "Cortex", "29", "Miata", "XXM", "Takara", "Yukon",
- "Tsunami", "Wildfire", "CUSCO"
+#ifdef CONFIG_ALPHA_GENERIC
+ static struct alpha_machine_vector *systype_vecs[] __initlocaldata =
+ {
+ NULL, /* 0 */
+ NULL, /* ADU */
+ NULL, /* Cobra */
+ NULL, /* Ruby */
+ NULL, /* Flamingo */
+ NULL, /* Mannequin */
+ &jensen_mv,
+ NULL, /* Pelican */
+ NULL, /* Morgan */
+ NULL, /* Sable -- see below. */
+ NULL, /* Medulla */
+ &noname_mv,
+ NULL, /* Turbolaser */
+ &avanti_mv,
+ NULL, /* Mustang */
+ &alcor_mv, /* Alcor, Bret, Maverick. */
+ NULL, /* Tradewind */
+ NULL, /* Mikasa -- see below. */
+ NULL, /* EB64 */
+ NULL, /* EB66 -- see variation. */
+ NULL, /* EB64+ -- see variation. */
+ &alphabook1_mv,
+ &rawhide_mv,
+ NULL, /* K2 */
+ NULL, /* Lynx */
+ &xl_mv,
+ NULL, /* EB164 -- see variation. */
+ NULL, /* Noritake -- see below. */
+ NULL, /* Cortex */
+ NULL, /* 29 */
+ &miata_mv,
+ NULL, /* XXM */
+ &takara_mv,
+ NULL, /* Yukon */
+ &dp264_mv,
+ NULL, /* Wildfire */
+ NULL, /* CUSCO */
};
- static char *unofficial_names[] = {"100", "Ruffian"};
+ static struct alpha_machine_vector *unofficial_vecs[] __initlocaldata =
+ {
+ NULL, /* 100 */
+ &ruffian_mv,
+ };
- static char * eb164_names[] = {"EB164", "PC164", "LX164", "SX164"};
- static int eb164_indices[] = {0,0,0,1,1,1,1,1,2,2,2,2,3,3,3,3};
+ static struct alpha_machine_vector *alcor_vecs[] __initlocaldata =
+ {
+ &alcor_mv, &xlt_mv, &xlt_mv
+ };
- static char * alcor_names[] = {"Alcor", "Maverick", "Bret"};
- static int alcor_indices[] = {0,0,0,1,1,1,0,0,0,0,0,0,2,2,2,2,2,2};
+ static struct alpha_machine_vector *eb164_vecs[] __initlocaldata =
+ {
+ &eb164_mv, &pc164_mv, &lx164_mv, &sx164_mv
+ };
- static char * eb64p_names[] = {"EB64+", "Cabriolet", "AlphaPCI64"};
- static int eb64p_indices[] = {0,0,1,2};
+ static struct alpha_machine_vector *eb64p_vecs[] __initlocaldata =
+ {
+ &eb64p_mv,
+ &cabriolet_mv,
+ NULL /* AlphaPCI64 */
+ };
- static char * eb66_names[] = {"EB66", "EB66+"};
- static int eb66_indices[] = {0,0,1};
+ static struct alpha_machine_vector *eb66_vecs[] __initlocaldata =
+ {
+ &eb66_mv,
+ &eb66p_mv
+ };
+
+ /* ??? Do we need to distinguish between Rawhides? */
- static char * rawhide_names[] = {"Dodge", "Wrangler", "Durango",
- "Tincup", "DaVinci"};
- static int rawhide_indices[] = {0,0,0,1,1,2,2,3,3,4,4};
+ struct alpha_machine_vector *vec;
+ /* Restore real CABRIO and EB66+ family names, ie EB64+ and EB66 */
+ if (type < 0)
+ type = -type;
+
+ /* Search the system tables first... */
+ vec = NULL;
+ if (type < N(systype_vecs)) {
+ vec = systype_vecs[type];
+ } else if ((type > ST_UNOFFICIAL_BIAS) &&
+ (type - ST_UNOFFICIAL_BIAS) < N(unofficial_vecs)) {
+ vec = unofficial_vecs[type - ST_UNOFFICIAL_BIAS];
+ }
+
+ /* If we've not found one, try for a variation. */
+
+ if (!vec) {
+ /* Member ID is a bit-field. */
+ long member = (variation >> 10) & 0x3f;
+
+ switch (type) {
+ case ST_DEC_ALCOR:
+ if (member < N(alcor_indices))
+ vec = alcor_vecs[alcor_indices[member]];
+ break;
+ case ST_DEC_EB164:
+ if (member < N(eb164_indices))
+ vec = eb164_vecs[eb164_indices[member]];
+ break;
+ case ST_DEC_EB64P:
+ if (member < N(eb64p_indices))
+ vec = eb64p_vecs[eb64p_indices[member]];
+ break;
+ case ST_DEC_EB66:
+ if (member < N(eb66_indices))
+ vec = eb66_vecs[eb66_indices[member]];
+ break;
+ case ST_DEC_1000:
+ if (cpu == EV5_CPU)
+ vec = &mikasa_primo_mv;
+ else
+ vec = &mikasa_mv;
+ break;
+ case ST_DEC_NORITAKE:
+ if (cpu == EV5_CPU)
+ vec = &noritake_primo_mv;
+ else
+ vec = &noritake_mv;
+ break;
+ case ST_DEC_2100_A500:
+ if (cpu == EV5_CPU)
+ vec = &sable_gamma_mv;
+ else
+ vec = &sable_mv;
+ break;
+ }
+ }
+ return vec;
+#else
+ /* TODO: verify that the system is of the type for which we
+ were configured. For now, cop out and return success. */
+ return &alpha_mv;
+#endif /* GENERIC */
+}
+
+static struct alpha_machine_vector * __init
+get_sysvec_byname(const char *name)
+{
+#ifdef CONFIG_ALPHA_GENERIC
+ static struct alpha_machine_vector *all_vecs[] __initlocaldata =
+ {
+ &alcor_mv,
+ &alphabook1_mv,
+ &avanti_mv,
+ &cabriolet_mv,
+ &dp264_mv,
+ &eb164_mv,
+ &eb64p_mv,
+ &eb66_mv,
+ &eb66p_mv,
+ &jensen_mv,
+ &lx164_mv,
+ &miata_mv,
+ &mikasa_mv,
+ &mikasa_primo_mv,
+ &noname_mv,
+ &noritake_mv,
+ &noritake_primo_mv,
+ &p2k_mv,
+ &pc164_mv,
+ &rawhide_mv,
+ &ruffian_mv,
+ &sable_mv,
+ &sable_gamma_mv,
+ &sx164_mv,
+ &takara_mv,
+ &xl_mv,
+ &xlt_mv
+ };
+
+ int i, n = sizeof(all_vecs)/sizeof(*all_vecs);
+ for (i = 0; i < n; ++i) {
+ struct alpha_machine_vector *mv = all_vecs[i];
+ if (strcasecmp(mv->vector_name, name) == 0)
+ return mv;
+ }
+ return NULL;
+#else
+ if (strcasecmp(alpha_mv.vector_name, name) == 0)
+ return &alpha_mv;
+ return NULL;
+#endif
+}
+
+static void
+get_sysnames(long type, long variation,
+ char **type_name, char **variation_name)
+{
long member;
/* Restore real CABRIO and EB66+ family names, ie EB64+ and EB66 */
@@ -353,9 +642,47 @@
break;
case ST_DEC_RAWHIDE:
if (member < N(rawhide_indices))
- *variation_name = rawhide_names[rawhide_indices[member]];
+ *variation_name = rawhide_names[rawhide_indices[member]];
break;
- } /* end family switch */
+ }
+}
+
+/*
+ * A change was made to the HWRPB via an ECO and the following code
+ * tracks a part of the ECO. In HWRPB versions less than 5, the ECO
+ * was not implemented in the console firmware. If it's revision 5 or
+ * greater we can get the name of the platform as an ASCII string from
+ * the HWRPB. That's what this function does. It checks the revision
+ * level and if the string is in the HWRPB it returns the address of
+ * the string--a pointer to the name of the platform.
+ *
+ * Returns:
+ * - Pointer to a ASCII string if it's in the HWRPB
+ * - Pointer to a blank string if the data is not in the HWRPB.
+ */
+
+static char *
+platform_string(void)
+{
+ struct dsr_struct *dsr;
+ static char unk_system_string[] = "N/A";
+
+ /* Go to the console for the string pointer.
+ * If the rpb_vers is not 5 or greater the rpb
+ * is old and does not have this data in it.
+ */
+ if (hwrpb->revision < 5)
+ return (unk_system_string);
+ else {
+ /* The Dynamic System Recognition struct
+ * has the system platform name starting
+ * after the character count of the string.
+ */
+ dsr = ((struct dsr_struct *)
+ ((char *)hwrpb + hwrpb->dsr_offset));
+ return ((char *)dsr + (dsr->sysname_off +
+ sizeof(long)));
+ }
}
/*
@@ -363,20 +690,21 @@
*/
int get_cpuinfo(char *buffer)
{
- static char *cpu_names[] = {
- "EV3", "EV4", "Unknown", "LCA4", "EV5", "EV45", "EV56",
- "EV6", "PCA56", "PCA57"
- };
-
extern struct unaligned_stat {
unsigned long count, va, pc;
} unaligned[2];
+ static char cpu_names[][8] = {
+ "EV3", "EV4", "Unknown", "LCA4", "EV5", "EV45", "EV56",
+ "EV6", "PCA56", "PCA57"
+ };
+
struct percpu_struct *cpu;
unsigned int cpu_index;
char *cpu_name;
char *systype_name;
char *sysvariation_name;
+ int len;
cpu = (struct percpu_struct*)((char*)hwrpb + hwrpb->processor_offset);
cpu_index = (unsigned) (cpu->type - 1);
@@ -387,30 +715,25 @@
get_sysnames(hwrpb->sys_type, hwrpb->sys_variation,
&systype_name, &sysvariation_name);
- return sprintf(buffer,
- "cpu\t\t\t: Alpha\n"
- "cpu model\t\t: %s\n"
- "cpu variation\t\t: %ld\n"
- "cpu revision\t\t: %ld\n"
- "cpu serial number\t: %s\n"
- "system type\t\t: %s\n"
- "system variation\t: %s\n"
- "system revision\t\t: %ld\n"
- "system serial number\t: %s\n"
- "cycle frequency [Hz]\t: %lu\n"
- "timer frequency [Hz]\t: %lu.%02lu\n"
- "page size [bytes]\t: %ld\n"
- "phys. address bits\t: %ld\n"
- "max. addr. space #\t: %ld\n"
- "BogoMIPS\t\t: %lu.%02lu\n"
- "kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
- "user unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
- "platform string\t\t: %s\n"
-#ifdef __SMP__
- "%s"
-#endif
- ,
-
+ len = sprintf(buffer,
+ "cpu\t\t\t: Alpha\n"
+ "cpu model\t\t: %s\n"
+ "cpu variation\t\t: %ld\n"
+ "cpu revision\t\t: %ld\n"
+ "cpu serial number\t: %s\n"
+ "system type\t\t: %s\n"
+ "system variation\t: %s\n"
+ "system revision\t\t: %ld\n"
+ "system serial number\t: %s\n"
+ "cycle frequency [Hz]\t: %lu\n"
+ "timer frequency [Hz]\t: %lu.%02lu\n"
+ "page size [bytes]\t: %ld\n"
+ "phys. address bits\t: %ld\n"
+ "max. addr. space #\t: %ld\n"
+ "BogoMIPS\t\t: %lu.%02lu\n"
+ "kernel unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
+ "user unaligned acc\t: %ld (pc=%lx,va=%lx)\n"
+ "platform string\t\t: %s\n",
cpu_name, cpu->variation, cpu->revision,
(char*)cpu->serial_no,
systype_name, sysvariation_name, hwrpb->sys_revision,
@@ -424,9 +747,11 @@
loops_per_sec / 500000, (loops_per_sec / 5000) % 100,
unaligned[0].count, unaligned[0].pc, unaligned[0].va,
unaligned[1].count, unaligned[1].pc, unaligned[1].va,
- platform_string()
+ platform_string());
+
#ifdef __SMP__
- , smp_info()
+ return len + smp_info(buffer+len);
+#else
+ return len;
#endif
- );
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov